Matplotlib 绘图

matplotlib初尝试


In [2]:
# 导入pyplot模块
import matplotlib.pyplot as plt
# 传入要绘制的数据
plt.plot([1,2,3,4])
# 绘制line2D对象
plt.show()


如果只是将一个列表传入plt.plot()函数,matplotlib 默认传入的是y值,于是将序列的x的值对应起来,x取值分别为0,1,2,...


In [4]:
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.show()



In [5]:
# 修改坐标轴的范围
plt.axis([0,5,0,20])
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.show()


使用numpy作为传入数据


In [6]:
import math
import numpy as np
t = np.arange(0,2.5,0.1)
y1 = map(math.sin, math.pi*t)
y2 = map(math.cos, math.pi*t + math.pi/2)
y3 = map(math.sin, math.pi*t - math.pi/2)
plt.plot(t,y1,'b*',t,y2,'g^',t,y3,'ys')
plt.show()


修改表现形式


In [7]:
plt.plot(t,y1,'b--',t,y2,'g',t,y3,'r-.')
plt.show()


使用kwargs

在使用中,属性使用的是默认值,也可以使用 keyword args 设置

设置线宽


In [13]:
plt.plot([1,2,4,2,1,0,1,2,1,4],linewidth=2.0)
plt.show()


处理过个 figure 和 axes 对象

subplot()函数使用参数设置分区模式和当前子图,第一个数字决定将图形的沿垂直方向分成几个部分,第二个数字决定将图形水平方向分割成几个部分,第三个参数设定可以直接设定的命令控制的子图。


In [17]:
t = np.arange(0,5,0.1)
y1 = np.sin(2*np.pi*t)
y2 = np.sin(2*np.pi*t)
plt.subplot(211)
plt.plot(t,y1,'b--')
plt.subplot(212)
plt.plot(t,y2,'r--')
plt.show()



In [19]:
t = np.arange(0.,1.,0.05)
y1 = np.sin(2*np.pi*t)
y2 = np.cos(2*np.pi*t)
plt.subplot(121)
plt.plot(t,y1,'b-.')
plt.subplot(122)
plt.plot(t,y2,'r--')
plt.show()


为图表添加更多的元素

为了图表表现能力更加丰富,很多时候添加线条和符号表示数据

添加文本


In [21]:
plt.axis([0,5,0,20])
plt.title('My first plot')
plt.xlabel('Counting')
plt.ylabel('Square values')
plt.plot([1,2,3,4],[1,3,9,16],'ro')
plt.show()


使用关键字参数修改文本属性,修改标题的字体,字号,颜色等等。


In [23]:
plt.axis([0,5,0,20])
plt.title('my first plot', fontsize=20, fontname='Times New Roman')
plt.xlabel('Counting', color='red')
plt.ylabel('square values', color='gray')
plt.plot([1,2,3,4],[1,3,9,16],'ro')
plt.show()


pyplot 允许在图表任意位置添加文本,由text函数完成

text(x,y,s,fontdict=None,**kwargs)

In [24]:
plt.axis([0,5,0,20])
plt.title('my first plot', fontsize=20, fontname='Times New Roman')
plt.xlabel('Counting', color='gray')
plt.ylabel('square values', color='gray')
plt.text(1,1.5,'first')
plt.text(2,4.5,'second')
plt.text(3,9.5,'third')
plt.text(4,16.5,'fourth')
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.show()


pyplot 还支持 $LaTex$ 标注


In [25]:
plt.axis([0,5,0,20])
plt.title('my first plot', fontsize=20, fontname='Times New Roman')
plt.xlabel('Counting', color='gray')
plt.ylabel('square values', color='gray')
plt.text(1,1.5,'first')
plt.text(2,4.5,'second')
plt.text(3,9.5,'third')
plt.text(4,16.5,'fourth')
plt.text(1.1,12,r'$y=x^2$',fontsize=20,bbox={'facecolor':'yellow','alpha':0.2})
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.show()


添加网格

添加网格非常简单,只需要添加grid()函数即可


In [2]:
import matplotlib.pyplot as plt
import numpy as np
plt.axis([0,5,0,20])
plt.title('my first plot', fontsize=20, fontname='Times New Roman')
plt.xlabel('Counting', color='gray')
plt.ylabel('square values', color='gray')
plt.text(1,1.5,'first')
plt.text(2,4.5,'second')
plt.text(3,9.5,'third')
plt.text(4,16.5,'fourth')
plt.text(1.1,12,r'$y=x^2$',fontsize=20,bbox={'facecolor':'yellow','alpha':0.2})
plt.grid(True)
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.show()


添加图例


In [3]:
plt.axis([0,5,0,20])
plt.title('my first plot', fontsize=20, fontname='Times New Roman')
plt.xlabel('Counting', color='gray')
plt.ylabel('square values', color='gray')
plt.text(1,1.5,'first')
plt.text(2,4.5,'second')
plt.text(3,9.5,'third')
plt.text(4,16.5,'fourth')
plt.text(1.1,12,r'$y=x^2$',fontsize=20,bbox={'facecolor':'yellow','alpha':0.2})
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.legend(['first series'])
plt.show()


图例默认是在图形的右上角,如果修改图例的位置,可以有loc关键字控制

位置编号 位置描述
0 最佳位置
1 右上角
2 左上角
3 右下角
4 左下角
5 右侧
6 左侧垂直居中
7 右侧垂直居中
8 下方水平居中
9 上方水平居中
10 正中间

图例中使用多个序列


In [4]:
plt.axis([0,5,0,20])
plt.title('my first plot', fontsize=20, fontname='Times New Roman')
plt.xlabel('Counting', color='gray')
plt.ylabel('square values', color='gray')
plt.text(1,1.5,'first')
plt.text(2,4.5,'second')
plt.text(3,9.5,'third')
plt.text(4,16.5,'fourth')
plt.text(1.1,12,r'$y=x^2$',fontsize=20,bbox={'facecolor':'yellow','alpha':0.2})
plt.grid(True)
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.plot([1,2,3,4],[0.8,3,5,15],'g^')
plt.plot([1,2,3,4],[0.5,2.5,4,12],'b*')
plt.legend(['first series','second series','third series'],loc=2)
plt.show()


处理日期


In [6]:
import datetime
events = [datetime.date(2015,1,23),datetime.date(2015,1,28),datetime.date(2015,2,3),
          datetime.date(2015,2,21),datetime.date(2015,3,15),datetime.date(2015,3,24),
         datetime.date(2015,4,8),datetime.date(2015,4,24)]
reading=[12,23,25,20,18,15,17,14]
plt.plot(events,reading)
plt.show()


从上面例子可以看出,生成的横轴非常难看,需要进一步处理


In [11]:
import datetime
import matplotlib.dates as mdates
months = mdates.MonthLocator()
days = mdates.DayLocator()
timeFmt= mdates.DateFormatter('%Y-%m')
events = [datetime.date(2015,1,23),datetime.date(2015,1,28),datetime.date(2015,2,3),
          datetime.date(2015,2,21),datetime.date(2015,3,15),datetime.date(2015,3,24),
         datetime.date(2015,4,8),datetime.date(2015,4,24)]
reading=[12,23,25,20,18,15,17,14]
fig,ax = plt.subplots()
plt.plot(events,reading)
ax.xaxis.set_major_locator(months)
ax.xaxis.set_major_formatter(timeFmt)
ax.xaxis.set_minor_locator(days)
plt.show()


图表类型

线形图

$$y=\frac{sin(3\cdot x)}{x}$$

In [12]:
x = np.arange(-2*np.pi,2*np.pi,0.01)
y = np.sin(3*x)/x
plt.plot(x,y)
plt.show()


$$y=\frac{sin(n\cdot x)}{x}$$

In [13]:
x = np.arange(-2*np.pi,2*np.pi,0.01)
y1 = np.sin(1*x)/x
y2 = np.sin(2*x)/x
y3 = np.sin(3*x)/x
plt.plot(x,y1)
plt.plot(x,y2)
plt.plot(x,y3)
plt.show()


修改线型颜色和宽度


In [14]:
x = np.arange(-2*np.pi,2*np.pi,0.01)
y1 = np.sin(1*x)/x
y2 = np.sin(2*x)/x
y3 = np.sin(3*x)/x
plt.plot(x,y1,'k--',linewidth=3)
plt.plot(x,y2,'m-.')
plt.plot(x,y3,color='#87a3cc',linestyle='--')
plt.show()


颜色的种类

编码 颜色
b 蓝色
g 绿色
r 红色
c 蓝绿色
m 洋红色
y 黄色
k 黑色
w 白色

修改坐标轴的刻度表示


In [15]:
x = np.arange(-2*np.pi,2*np.pi,0.01)
y1 = np.sin(1*x)/x
y2 = np.sin(2*x)/x
y3 = np.sin(3*x)/x
plt.plot(x,y1,color='b')
plt.plot(x,y2,color='r')
plt.plot(x,y3,color='g')
plt.xticks([-2*np.pi, -np.pi,0,np.pi,2*np.pi],
          [r'$-2\pi$',r'$-\pi$',r'$0$',r'$+\pi$',r'$+2\pi$'])
plt.yticks([-1,0,+1,+2,+3],
          [r'$-1$',r'$0$',r'$+1$',r'$+2$',r'$+3$'])
plt.show()


绘制类似笛卡尔坐标系图


In [16]:
x = np.arange(-2*np.pi,2*np.pi,0.01)
y1 = np.sin(1*x)/x
y2 = np.sin(2*x)/x
y3 = np.sin(3*x)/x
plt.plot(x,y1,color='b')
plt.plot(x,y2,color='r')
plt.plot(x,y3,color='g')
plt.xticks([-2*np.pi, -np.pi,0,np.pi,2*np.pi],
          [r'$-2\pi$',r'$-\pi$',r'$0$',r'$+\pi$',r'$+2\pi$'])
plt.yticks([-1,0,+1,+2,+3],
          [r'$-1$',r'$0$',r'$+1$',r'$+2$',r'$+3$'])
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
plt.show()


annotate()函数尝试


In [18]:
x = np.arange(-2*np.pi,2*np.pi,0.01)
y1 = np.sin(1*x)/x
y2 = np.sin(2*x)/x
y3 = np.sin(3*x)/x
plt.plot(x,y1,color='b')
plt.plot(x,y2,color='r')
plt.plot(x,y3,color='g')
plt.xticks([-2*np.pi, -np.pi,0,np.pi,2*np.pi],
          [r'$-2\pi$',r'$-\pi$',r'$0$',r'$+\pi$',r'$+2\pi$'])
plt.yticks([-1,0,+1,+2,+3],
          [r'$-1$',r'$0$',r'$+1$',r'$+2$',r'$+3$'])
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
plt.annotate(r'$lim_{x\to 0}\frac{\sin(x)}{x} =1$',
            xy=[0,1],xycoords='data',
            xytext=[30,30],fontsize=16, textcoords='offset points', 
             arrowprops=dict(arrowstyle='->',connectionstyle='arc3,rad=.2'))
plt.show()


pandas数据绘制


In [19]:
import pandas as pd
data = {'series1':[1,3,4,3,5],
       'series2':[2,4,5,2,4],
       'series3':[3,2,3,1,2]}
df = pd.DataFrame(data)
x = np.arange(5)
plt.axis([0,5,0,7])
plt.plot(x,df)
plt.legend(data,loc=2)
plt.show()


直方图


In [20]:
pop = np.random.randint(0,100,100)
plt.hist(pop,bins=20)
plt.show()


条状图

与直方图类似,不过x轴表示的不是数值,而是类别


In [22]:
index =[0,1,2,3,4]
values = [5,7,3,4,6]
plt.bar(index,values)
plt.show()



In [24]:
index =np.arange(5)
values = [5,7,3,4,6]
plt.bar(index,values)
plt.xticks(index+0.4,['A','B','C','D','E'])
plt.show()


bar 关键字参数控制


In [27]:
index =np.arange(5)
values = [5,7,3,4,6]
std = [0.8,1,0.4,0.9,1.3]
plt.title('A bar charts')
plt.bar(index,values,yerr=std,error_kw={'ecolor':'0.1','capsize':6},alpha=0.7,label='First')
plt.xticks(index+0.4,['A','B','C','D','E'])
plt.legend(loc=2)
plt.show()


水平方向直方图


In [30]:
index =np.arange(5)
values = [5,7,3,4,6]
std = [0.8,1,0.4,0.9,1.3]
plt.title('A horizontal bar chart')
plt.barh(index,values,xerr=std,error_kw={'ecolor':'0.1','capsize':6},alpha=0.7,label='First')
plt.yticks(index+0.4,['A','B','C','D','E'])
'plt.legend(loc=5)'
plt.show()


多序列的条状图


In [33]:
index = np.arange(5)
value1 = [5,7,3,4,5]
value2 = [6,6,4,5,7]
value3 = [5,6,5,4,6]
bw =0.3
plt.axis([0,5,0,8])
plt.title('A Multiseries Bar Chart',fontsize=20)
plt.bar(index,value1,bw,color='b')
plt.bar(index+bw,value2,bw,color='g')
plt.bar(index+2*bw,value3,bw,color='r')
plt.xticks(index+1.5*bw,['A','B','C','D','E'])
plt.show()



In [34]:
index = np.arange(5)
value1 = [5,7,3,4,5]
value2 = [6,6,4,5,7]
value3 = [5,6,5,4,6]
bw =0.3
plt.axis([0,8,0,5])
plt.title('A Multiseries Horizontal Bar Chart',fontsize=20)
plt.barh(index,value1,bw,color='b')
plt.barh(index+bw,value2,bw,color='g')
plt.barh(index+2*bw,value3,bw,color='r')
plt.yticks(index+1.5*bw,['A','B','C','D','E'])
plt.show()


pandas DataFrame 生成多序列数据


In [39]:
data ={'series1':[1,3,4,3,5],
      'series2':[2,4,5,2,4],
      'series3':[3,2,3,1,3]}
df = pd.DataFrame(data)
df.plot(kind='bar')
plt.show()


多序列堆积条状图

为每个bar函数添加bottom关键字参数,把每个序列赋给相应的bottom关键字参数


In [40]:
series1 = np.array([3,4,5,3])
series2 = np.array([1,2,2,5])
series3 = np.array([2,3,3,4])
index = np.arange(4)
plt.axis([0,4,0,15])
plt.bar(index,series1,color='r')
plt.bar(index,series2,color='b',bottom=series1)
plt.bar(index,series3,color='g',bottom=(series1+series2))
plt.xticks(index+0.4,['Jan','Feb','Mar','Apr'])
plt.show()


也可以使用横轴叠加,只不过要将bottom修改为left


In [43]:
series1 = np.array([3,4,5,3])
series2 = np.array([1,2,2,5])
series3 = np.array([2,3,3,4])
index = np.arange(4)
plt.axis([0,15,0,4])
plt.barh(index,series1,color='r')
plt.barh(index,series2,color='b',left=series1)
plt.barh(index,series3,color='g',left=(series1+series2))
plt.yticks(index+0.4,['Jan','Feb','Mar','Apr'])
plt.show()


使用不同的形状填充bar


In [44]:
series1 = np.array([3,4,5,3])
series2 = np.array([1,2,2,5])
series3 = np.array([2,3,3,4])
index = np.arange(4)
plt.axis([0,15,0,4])
plt.barh(index,series1,color='w',hatch='xx')
plt.barh(index,series2,color='w',hatch='///',left=series1)
plt.barh(index,series3,color='w',hatch='\\\\\\',left=(series1+series2))
plt.yticks(index+0.4,['Jan','Feb','Mar','Apr'])
plt.show()


pandas 数据绘制堆积条状图


In [45]:
data = {'series1':[1,3,4,3,5],
       'series2':[2,4,5,2,4],
       'series3':[3,2,3,1,3]}
df = pd.DataFrame(data)
df.plot(kind='bar',stacked=True)
plt.show()


条状对比图


In [51]:
x0 = np.arange(8)
y1 = np.array([1,3,4,6,4,3,2,1])
y2 = np.array([1,2,5,4,3,3,2,1])
plt.ylim(-7,7)
plt.bar(x0,y1,0.9,facecolor='r',edgecolor='w')
plt.bar(x0,-y2,0.9,facecolor='b',edgecolor='w')
plt.xticks(())
plt.grid(True)
for x,y in zip(x0,y1):
    plt.text(x+0.4,y+0.05,'%d' % y,ha='center',va='bottom')
for x,y in zip(x0,y2):
    plt.text(x+0.4,-y-0.05,'%d' % y,ha='center',va='top')
plt.show()


饼状图

绘制简单


In [56]:
labels = ['nokia','samsung','apple','lumia']
values = [10,30,45,15]
colors = ['yellow','green','red','blue']
plt.pie(values,labels=labels,colors=colors)
plt.axis('equal')
plt.show()


脱离整体

指定explode参数,取值范围为0-1,0表示不脱离整理,1表示完全脱离整理,startangle调整饼图旋转的角度。


In [60]:
labels = ['nokia','samsung','apple','lumia']
values = [10,30,45,15]
colors = ['yellow','green','red','blue']
expode =[0.3,0,0,0]
plt.title('a pie chart')
plt.pie(values,labels=labels,colors=colors,explode=expode,startangle=180)
plt.axis('equal')
plt.show()


增加阴影和百分比

autopct关键字增加百分比,shadow关键字增加阴影效果


In [62]:
labels = ['nokia','samsung','apple','lumia']
values = [10,30,45,15]
colors = ['yellow','green','red','blue']
expode =[0.3,0,0,0]
plt.title('a pie chart')
plt.pie(values,labels=labels,colors=colors,explode=expode,startangle=180
       ,shadow=True,autopct='%1.1f%%')
plt.axis('equal')
plt.show()


DataFrame创建饼图


In [64]:
df['series1'].plot(kind='pie',figsize=(6,6))
plt.show()


等值线图

首先要定义$z=f(x,y)$函数生成一个三维结构,然后用x,y的取值范围,确定要显示的区域。之后使用$f(x,y)$函数计算每一对$(x,y)$所对应的z值,得到一个z矩阵,最后用contour()函数生成一个三维结构的表面的等值线图。定义颜色表,为等值线天机不同的颜色。


In [69]:
dx = 0.01
dy = 0.01
x = np.arange(-2.0,2.0,dx)
y = np.arange(-2.0,2.0,dy)
X,Y = np.meshgrid(x,y)
def f(x,y):
    return (1- y**5+x**5)*np.exp(-x**2-y**2)
C = plt.contour(X,Y,f(X,Y),8,colors='black')
plt.contourf(X,Y,f(X,Y),8)
plt.clabel(C,inline=4,fontsize=10)
plt.show()



In [73]:
dx = 0.01
dy = 0.01
x = np.arange(-2.0,2.0,dx)
y = np.arange(-2.0,2.0,dy)
X,Y = np.meshgrid(x,y)
def f(x,y):
    return (1- y**5+x**5)*np.exp(-x**2-y**2)
C = plt.contour(X,Y,f(X,Y),8,colors='black')
plt.contourf(X,Y,f(X,Y),8,cmap=plt.cm.hot)
plt.clabel(C,inline=1,fontsize=10)
plt.colorbar()
plt.show()


级区图

每一块区域占据了一定的角度,每块区域的半径$r$和它所占的角度,也就是极坐标$(r,\theta)$


In [74]:
N = 8
theta = np.arange(0.,2*np.pi,2*np.pi / N)
radii = np.array([4,7,5,3,1,5,6,7])
plt.axes([0.025,0.025,0.95,0.95],polar=True)
colors = np.array(['#4bb2c5','#c5b47f','#eaa228','#579575','#839557','#958c12'
                  ,'#953579','#4b5de4'])
bars = plt.bar(theta,radii,width=(2*np.pi/N),bottom=0,color=colors)
plt.show()


mplot3d 工具

3D 曲面


In [77]:
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = Axes3D(fig)
X = np.arange(-2,2,0.1)
Y = np.arange(-2,2,0.1)
X,Y = np.meshgrid(X,Y)
def f(x,y):
    return (1 - y**5+x**5)*np.exp(-x**2-y**2)
ax.plot_surface(X,Y,f(X,Y),rstride=1,cstride=1)
plt.show()


旋转曲面,调整高度和视角


In [78]:
fig = plt.figure()
ax = Axes3D(fig)
X = np.arange(-2,2,0.1)
Y = np.arange(-2,2,0.1)
X,Y = np.meshgrid(X,Y)
def f(x,y):
    return (1 - y**5+x**5)*np.exp(-x**2-y**2)
ax.plot_surface(X,Y,f(X,Y),rstride=1,cstride=1,cmap=plt.cm.hot)
ax.view_init(elev=30,azim=125)
plt.show()


3D 散点图


In [79]:
xs = np.random.randint(30,40,100)
ys = np.random.randint(20,30,100)
zs = np.random.randint(10,20,100)
xs2 = np.random.randint(50,60,100)
ys2 = np.random.randint(30,40,100)
zs2 = np.random.randint(50,70,100)
xs3 = np.random.randint(10,30,100)
ys3 = np.random.randint(40,50,100)
zs3 = np.random.randint(40,50,100)
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(xs,ys,zs)
ax.scatter(xs2,ys2,zs2,c='r',marker='^')
ax.scatter(xs3,ys3,zs3,c='g',marker='*')
ax.set_label('X Label')
ax.set_label('Y Label')
ax.set_label('Z Label')
plt.show()


多面板图形


In [80]:
fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
inner_ax = fig.add_axes([0.6,0.6,0.25,0.25])
plt.show()



In [81]:
fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
inner_ax = fig.add_axes([0.6,0.6,0.25,0.25])
x1 = np.arange(10)
y1 = np.array([1,2,7,1,5,2,4,2,3,1])
x2 = np.arange(10)
y2 = np.array([1,3,4,5,4,5,2,6,4,3])
ax.plot(x1,y1)
inner_ax.plot(x2,y2)
plt.show()



In [ ]: