Python绘图实践记录

用Python进行数据分析少不了绘图工具matplotlib

  • matplotlib是免费的,首先,应该确保环境已经安装matplotlib,numpy, mpl_toolkits,具体怎么做应该不用说了吧!

matplotlib是Python常用的数据绘制包。它基于numpy的数组运算功能。matplotlib绘图功能强大,可以轻易的画出各种统计图形,比如散点图,条行图,饼图等。matplotlib常与numpy和scipy相配合,用于许多研究领域。

二维绘图

  • 基本图形绘制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0,10,1000)
y = np.sin(x)
z = np.cos(x)
# 配置
plt.figure(figsize=(8,4)) # 框的大小
plt.plot(x,y,label='$sin(x)$')
plt.plot(x,z,'b--',label='$cos(x)$') # 蓝色虚线
plt.xlabel("Time(s)")
plt.ylabel("")
plt.title("matplotlib")
plt.ylim(-1.2, 1.2)
plt.legend() # 显示为一个样式
plt.show()

fig = plt.gcf() # 获得当前图标的对象
ax = plt.gca() # 获得子图的对象
print fig
print ax
  • 多轴绘图
1
2
3
4
5
6
7
8
9
#   多轴绘图
# subplot(numRows, numCols, plotNum)

import matplotlib.pyplot as plt

for idx, color in enumerate("rgbyck"):
plt.subplot(320+idx+1, axisbg=color)

plt.show()
  • 不同坐标系
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import numpy as np
import matplotlib.pyplot as plt

w = np.linspace(0.1, 1000, 1000)
p = np.abs(1/(1+0.1j*w))

plt.subplot(221)
plt.plot(w, p, linewidth=2) # 算术坐标系
plt.ylim(0, 1.5)

plt.subplot(222)
plt.semilogx(w, p, linewidth=2) # x 对数坐标系
plt.ylim(0, 1.5)

plt.subplot(223)
plt.semilogy(w, p, linewidth=2) # y 对数坐标系
plt.ylim(0, 1.5)

plt.subplot(224)
plt.loglog(w, p, linewidth=2) # 对数坐标系
plt.ylim(0, 1.5)

plt.show()
  • 柱状图
1
2
3
4
5
6
7
#   1.txt的文本
>>> data
array([[ 0., 10., 20., 30., 40.],
[ 10., 23., 33., 43., 53.],
[ 20., 83., 23., 55., 33.],
[ 30., 93., 44., 22., 55.],
[ 40., 72., 33., 44., 66.]])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import numpy as np
import matplotlib.pyplot as plt

data = np.loadtxt(r"D:\1.txt")
width = (data[1, 0] - data[0, 0])*0.4 # 柱形的宽带为4

# data[:, 0]:所有行数据
# data[:, 1]:所有列数据
plt.figure()
plt.bar(data[:, 0] - width, data[:, 1], width, label='person')
plt.xlim(-width, 40) # x 的取值区间
plt.xlabel("Age")
plt.ylabel("Num")

plt.legend()
plt.show()
  • 散点图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
import matplotlib.pyplot as plt

plt.figure()
x = np.random.rand(100)
y = np.random.rand(100)
# marker:绘制点的形状和大小,5代表五边形,1是大小
# s的默认值是20
plt.scatter(x, y, s=x*1000, c=y, marker=(5,1), lw=2, facecolor='none')
# marker:绘制点的形状和大小 lw:linewidth facecolor:颜色
plt.xlim(0, 1) # c:cmap不是color,cmap绘制出来是彩图(不同颜色)
plt.ylim(0, 1)

plt.show()

三维绘图(mpl_toolkits)

  • 基本3D图
1
2
3
4
5
6
7
8
#   3D图     
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = fig.gca(projection='3d') # projection='3d' 已经隐性调用了Axes3D

# ax = Axes3D(fig) # 可以加上也可以不加
th = np.linspace(-4 * np.pi, 4 * np.pi, 100)
z = np.linspace(-2, 2, 100)
r = z ** 2 + 1
x = r * np.sin(th)
y = r * np.cos(th)

ax.plot(x, y, z, label='hello') # 立体的
ax.legend()
plt.show()
ax.plot(x, y, label='hello') # 平面的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def randrange(n, vmin, vmax):
return (vmax-vmin)*np.random.rand(n) + vmin

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

n = 100
for c, m, zl, zh in [('r', 'o', -50, -25), ('b', '^', -30, -5)]:
xs = randrange(n, 23, 32)
ys = randrange(n, 0, 100)
zs = randrange(n, zl, zh)

ax.scatter(xs, ys, zs, c=c, marker=m)

ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')

plt.show()
  • 轮廓图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
from matplotlib import cm

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

X, Y, Z = axes3d.get_test_data(0.05) # 生成一系列的测试数据
cset = ax.contour(X, Y, Z,cmap=cm.coolwarm) # contour:生成轮廓图
ax.clabel(cset, fontsize=9, inline=1)
plt.show()

# 修改
cset = ax.contour(X, Y, Z,extend3d=True, cmap=cm.coolwarm) # 颜色的填充
  • 3D柱形图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

for c, z in zip(['r', 'g', 'b', 'y'], (30, 20, 10, 0)):
x = np.arange(20)
y = np.random.rand(20)
cs = [c] * len(x)
cs[0] = 'c'
ax.bar(x, y, zs=z, zdir='y', color = cs)

ax.set_xlabel('x')

plt.show()
  • 绘制曲面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

u = np.linspace(0, 2*np.pi, 100)
v = np.linspace(0, np.pi, 100)
x = 10 * np.outer(np.cos(u), np.sin(v))
y = 10 * np.outer(np.sin(u), np.sin(v))
z = 10 * np.outer(np.ones(np.size(u)), np.cos(v))

ax.plot_surface(x, y, z, rstride=4, cstride=4, color='b')
  • 绘制文字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.gca(projection='3d')

zdirs = (None, 'x', 'y', 'z', (1, 1, 0), (1, 1, 1))
xs = (1, 4, 4, 9, 4, 1)
ys = (2, 5, 8, 10, 1, 2)
zs = (10,3, 8, 9, 1, 8)

for zdir, x, y, z in zip(zdirs, xs, ys, zs):
label = '(%d, %d, %d), dir=%s' % (x, y, z, zdir)
ax.text(x, y, z, label, zdir)

ax.text(9, 0, 0, 'red', color='red')
ax.text2D(0.05, 0.95, "20 text", transform=ax.transAxes)

ax.set_xlim3d(0,10)
ax.set_ylim3d(0,10)
ax.set_zlim3d(0,10)

ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')

plt.show()

地图绘制(mpl_toolkits.basemap)

  • 基本思路

地图的大小、投影方法等重要信息,是在Basemap()的调用中实现的:
map = Basemap(projection=’ortho’,lat_0=35,lon_0=120,resolution=’l’)
projection参数规定了投影方法。改变投影方法,绘图结果也将非常不同。
城市所在位置是经纬度。我们想要把经纬度对应图像的像素点,需要转换:
x, y = map(lons, lats)
这个语句转换为图像上的位置。
最后,调用绘制散点图的方法scatter():
cs = map.scatter(i,j,s=size,marker=’o’,color=’#FF5600’)
在地图上画出数据。

  • 准备数据
1
2
3
4
5
6
7
8
9
10
11
# 保存到major_city.txt 
# 第一列是城市名,第二列是人口,第三第四列为纬度和经度,最后一列为所在国家。
Shanghai 23019148 31.23N 121.47E China
Mumbai 12478447 18.96N 72.82E India
Karachi 13050000 24.86N 67.01E Pakistan
Delhi 16314838 28.67N 77.21E India
Manila 11855975 14.62N 120.97E Philippines
Seoul 23616000 37.56N 126.99E Korea(South)
Jakarta 28019545 6.18S 106.83E Indonesia
Tokyo 35682460 35.67N 139.77E Japan
Peking 19612368 39.91N 116.39E China
  • 绘图代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np

#============================================# read data
names = []
pops = []
lats = []
lons = []
countries = []
for line in file("../data/major_city"):
info = line.split()
names.append(info[0])
pops.append(float(info[1]))
lat = float(info[2][:-1])
if info[2][-1] == 'S': lat = -lat
lats.append(lat)
lon = float(info[3][:-1])
if info[3][-1] == 'W': lon = -lon + 360.0
lons.append(lon)
country = info[4]
countries.append(country)

#============================================
# set up map projection with
# use low resolution coastlines.
map = Basemap(projection='ortho',lat_0=35,lon_0=120,resolution='l')
# draw coastlines, country boundaries, fill continents.
map.drawcoastlines(linewidth=0.25)
map.drawcountries(linewidth=0.25)
# draw the edge of the map projection region (the projection limb)
map.drawmapboundary(fill_color='#689CD2')
# draw lat/lon grid lines every 30 degrees.
map.drawmeridians(np.arange(0,360,30))
map.drawparallels(np.arange(-90,90,30))
# Fill continent wit a different color
map.fillcontinents(color='#BF9E30',lake_color='#689CD2',zorder=0)
# compute native map projection coordinates of lat/lon grid.
x, y = map(lons, lats)
max_pop = max(pops)
# Plot each city in a loop.
# Set some parameters
size_factor = 80.0
y_offset = 15.0
rotation = 30
for i,j,k,name in zip(x,y,pops,names):
size = size_factor*k/max_pop
cs = map.scatter(i,j,s=size,marker='o',color='#FF5600')
plt.text(i,j+y_offset,name,rotation=rotation,fontsize=10)

plt.title('Major Cities in Asia & Population')
plt.show()

以上是常用的matplotlib绘图方法,一下子可能很难全部记住,但是没关系,只要记得回来copy即可。