matplotlib架构
matplotlib架构分为三层:各层之间单向通信,即每一层只能与它的下一层通信,而下层无法与上层通信。
-
Scripting(脚本)层:
-
Artist(变现层):
-
Backend(后端层):
Backend层
-
在matplotlib的架构中,最下面一层为 Backend层。 matplotlib API即位于该层,这些是用来在底层实现图形元素的一个个类。
-
FigureCanvas对象实现了绘图区域这一概念。
-
Renderer对象在 Figure Canvas上绘图
-
Event对象处理用户输入(键盘和鼠标事件)。
Artist层
-
中间层为 Artist,层。图形中所有能看到的元素都属于 Artist对象,即标题、轴标签、刻度等组成图形的所有元素都是 Artis对象的实例。
-
Artist类分为两种:原始(primitive)和复合(composite)
-
绘制Line2D或矩形、圆形等几何图形,甚至文本等图形时,形成图形表示的基础元素由primitive artist单个对象组成。
-
由多个基础元素
primitive artist
组成的图表中的图像元素叫作 composite artist, -
Figure对象在 Artist层的最上面,对应整个图形表示,通常可包含多条轴(Axes)
-
Axes对象通常表示图形或图表是对什么内容进行作图的。每个Axes对象只属于一个Figure对象,由两个(三维就有三个) Artist axis对象组成。标题、x标签和y标签等对象都属于Axes这个composite artist类型的对象。
-
Axis对象负责展示在Axes对象上面的数值,定义数值范围,管理刻度(轴上的标记)和刻度值标签(代表每个刻度大小的文本标签)。刻度的位置用 Locator对象调整,刻度标签的格式用Formatter对象调整。
Scripting层(pyplot)
- plab模块跟 matplotlib一起安装,而pyplot则是 matplotlib的内部模块。两者的导入方法也有所不同,可选择其中一种进行导入。
from pylab import *
import matplotlib.pyplot as plt
import numpy as np
-
pylab在同一命名空间整合了 pyplot和 NumPy的功能,因此无需再单独导入 NumPy。更进一步来说,导人 pylab后, pyplot和 NumPy的函数就可以直接调用,而不用再指定其所属模块(命名空间),从而使得 matplotlib开发环境更像是 Matlab。
-
pyplot模块提供操作 matplotlib库的经典 Python编程接口,有着自己的命名空间,需要单独导入NumPy库
pyplot
-
通过pyplot函数可以操作或改动 Figure对象,例如创建 Figure对象和绘图区域、表示一条线或为图形添加标签等。
-
pyplot还具有状态性特性,它能跟踪当前图形和绘图区域的状态。调用函数时,函数只对当前图形起作用。
- 生成一幅简单的交互式图表
import matplotlib.pyplot as plt
plt.plot([1,2,3,4,5])
plt.show()
设置图形的属性
1.用红点来表示每一对(x,y)
import matplotlib.pyplot as plt
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.show()
2.title()函数增加标题。
plt.axis([0,5,0,20])
plt.title('The first')
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.show()
3.如何在同一图形中绘制三种不同的趋势图.
使用 kwargs
- 组成图表的各个对象有很多用以描述它们特点的属性。这些属性均有默认值,但可以用关键字参数设置。
这些关键字作为参数传递给函数。在matplotlib库各个函数的参考文档中,每个函数的最后个参数总是 kwargs。
matplotlib.pyplot.plot(*args, **kwargs)
- linewidth关键字参数,可以改变线条的粗细。
处理多个 Figure和Axes对象
- 可以同时管理多个图形,而在每个图形中,又可以绘制几个不同的子图。
因此,使用 pyplot时,必须时刻注意当前 Figure对象和当前Axes对象的概念(也就是 Figure对象中当前所显示的图形)
-
一幅图形中有两个子图
-
subplot(函数不仅可以将图形分为不同的绘图区域,还能激活特定子图,以便用命令控制它。
-
subplot()函数用参数设置分区模式和当前子图。只有当前子图会受到命令的影响。
-
subplot()函数的参数由三个整数组成:第一个数字决定图形沿垂直方向被分为几部分,第二个数字决定图形沿水平方向被分为几部分,第三个数字设定可以直接用命令控制的子图。
-
把画布分为上下两个向水平方向延伸的子图
import matplotlib.pyplot as plt
import numpy as np
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()
- 把图形分为左右两个子图。
t = np.arange(0,5,0.1)
y1= np.sin(2*np.pi*t)
y2= np.sin(2*np.pi*t)
plt.subplot(121)
plt.plot(t, y1, 'b-')
plt.subplot(122)
plt.plot(t,y2, 'r--')
plt.show()
添加文本
- xlabe()和 ylabel()函数专门用于添加轴标签。把要显示的文本以字符串形式传给这两个函数作为参数。
plt.axis([0,5,0,20])
plt.title('The first')
plt.xlabel('Counting')
plt.ylabel('Square Values')
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.show()
改变字体、字号和轴标签颜色
plt.axis([0,5,0,20])
plt.title('The first',fontsize=20,fontname='Times New Roman' )
plt.xlabel('Counting',color='gray' )
plt.ylabel('Square Values',color='gray')
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.show()
- pyplot允许你在图表任意位置添加文本。这个功能由text()函数来实现.
text(x, y, s, fontdict=None, **kwargs)
- 前两个参数为文本在图形中位置的坐标。s为要添加的字符串, fontdict(可选)为文本要使用的字体。最后,还可以使用关键字参数。
为图形的各个数据点添加标签。
- text()函数的前两个参数为标签在图形中位置的坐标,所以我们可以使用四个数据点的坐标作为各标签的坐标,但每个标签的y值较相应数据点的y值有一点偏差。
plt.axis([0,5,0,20])
plt.title('The first',fontsize=20,fontname='Times New Roman' )
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.xlabel('Counting',color='gray' )
plt.ylabel('Square Values',color='gray')
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.show()
添加公式
- matplotlib整合了LaTeX表达式,支持在图表中插入数学表达式。
将表达式内容置于两个符号之间,可在文本中添加 LaTeX表达式。解释器会将该符号之间的文本识别成 LaTex表达式,把它们转换为数学表达式、公式、数学符号或希腊字母等,然后在图像中显示出来。通常,需要在包含LaTeX表达式的字符串前添加r字符,表明它后面是原始文本,不能对其进行转义操作。
plt.axis([0,5,0,20])
plt.title('The first',fontsize=20,fontname='Times New Roman' )
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.xlabel('Counting',color='gray' )
plt.ylabel('Square Values',color='gray')
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.show()
添加网格
plt.grid(True)
添加图例
- legend()函数,用于操作该类对象。
plt.axis([0,5,0,20])
plt.title('The first',fontsize=20,fontname='Times New Roman' )
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.xlabel('Counting',color='gray' )
plt.ylabel('Square Values',color='gray')
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.legend(['first serises'])
plt.show()
- 如果要修改图例的位置,还是需要添加几个关键字参数。例如,图例的位置由loc关键字控制,其取值范围为0~10。每个数字代表图表中的
一处位置,默认为1,也就是右上角位置。
0:最佳位置
1:右上角
2:左上角
3:右下角
4:左下角
5:右侧
6:左侧垂直居中
7:右侧垂直居中
8:下方水平居中
9:上方水平居中
10:正中间
注意:通常,图例通过标签、颜色和(或)符号向读者表明这是哪一个序列,应该与其他序列区分开来。在前面所有的例子中,我们只使用了由一个p1ot()函数绘制的单个序列。
- 在一幅图中同时显示多个序列。图表中每个序列用一种特定的颜色和符号来表示。从代码实现的角度来看,每个序列都要调用一次plot()函数,调用顺序跟传给 legend()函数作为参数的文本标签顺序应保持一致。
plt.axis([0,5,0,20])
plt.title('The first',fontsize=20,fontname='Times New Roman' )
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.xlabel('Counting',color='gray' )
plt.ylabel('Square Values',color='gray')
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.plot([1,2,3,4],[0.8,3.5,8,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()
保存图表
-
保存代码
-
将回话转化成HTML
-
将图表直接转化成图片
plt.savefig('mychart.png')
注意:保存成图像的命令之前不要使用plt.show(),否则将得到空白图像。
处理日期值
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)]
readings=[12,22,25,20,18,15,17,14]
plt.plot(events, readings)
plt.show()
-
如果让 matplotlib自动管理刻度,尤其是刻度的标签,其后果无疑是一场灾难。以这种方式显示日期时,可读性很差,两个数据点之间的时间间隔不清晰,并且还存在重影现象。建议用合适的对象,定义时间尺度来管理日期。
-
首先需要导入matplotlib.dates模块,该模块专门用于管理日期类型的数据。然后,定义时间尺度。下面例子中,用 Monthlocator()和 DayLocator()函数,分别表示月份和日子。
-
日期格式也很重要,要避免出现重影问题或显示无效的日期数据,只显示必要的刻度标签就好。我们这里只显示年月,把这种格式作为参数传给
DateFormatter()函数。
- 定义好两个时间尺度,一个用于日期,一个用于月份。你可以在 xaxis对象上调用 set_major_locator()函数和set_minorl_orator()函数,为x轴设置两种不同的标签。此外,月份刻度标签的设置,需要用到 set_major_formatter()函数。
import datetime
import numpy as np
import matplotlib. pyplot as plt
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)]
readings=[12,22,25,20,18,15,17,14]
fig, ax= plt.subplots()
plt.plot(events, readings)
ax.xaxis.set_major_locator(months)
ax.xaxis.set_major_formatter(timeFmt)
ax.xaxis.set_minor_locator( days)
plt.show()
图表类型
线性表
y=sin(3*x)/x 图像
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-2*np.pi,2*np.pi,0.01)
y=np.sin(3*x)/x
plt.plot(x,y)
plt.show()
y=sin(n* x)/x的图像
x = np.arange(-2*np.pi,2*np.pi,0.01)
y=np.sin(3*x)/x
y1=np.sin(4*x)/x
y2=np.sin(5*x)/x
plt.plot(x,y)
plt.plot(x,y1)
plt.plot(x,y2)
plt.show()
-
可以用plot(函数的第三个参数指定颜色/线型,把这些设置所用的字符编码放到同一个字符串即可。
-
还可以使用两个单独的关键字参数,用 color指定颜色,用 linestyle指定线型
| 编码 | 颜色 |
| :--- | :--- |
| b | 蓝色 |
| g | 绿色 |
| r | 红色 |
| c | 蓝绿色 |
| m | 洋红 |
| y | 黄色 |
| k | 黑色 |
| w | 白色 |
-
x轴的数值范围为-2π~2π,但是刻度标签默认使用数值形式需要用π的倍数代替数值。
-
同理,可以替换y轴刻度的标签。方法是使用 sticks()和 sticks()函数,分别为每个函数传入两列数值。第一个列表存储刻度的位置,第二个列表存储刻度的标签。
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-2*np.pi,2*np.pi,0.01)
y=np.sin(3*x)/x
y1=np.sin(4*x)/x
y2=np.sin(5*x)/x
plt.plot(x,y,color='b')
plt.plot(x,y1,color='r')
plt.plot(x,y2,color='g' )
plt.xticks([-2*np.pi,-np.pi,0,np.pi,2*np.pi],
[r'$-2pi$',r'$-pi$',r'$0$',r'$+pi$',r'$+2pi$'])
plt.yticks([-1,0,+1,+2,+3],
[r'$-1$',r'$ 0 $',r'$+1$',r'$+2$',r'$+3$'])
plt.show()
-
前面的所有线性图中,x轴和轴总是置于 Figure的边缘(跟图像的边框重合)
-
另外一种显示轴的方法是,两条轴穿过原点(0,0),也就是笛卡儿坐标轴。
-
具体做法是,首先必须用gca()函数获取Axes对象。接着通过这个对象,指定每条边的位置:右、左、下和上,可选择组成图形边框的每条边。使用 set_color()函数,把颜色设置为none,删除跟坐标轴不符合的边(右和上)。然后,用 set_position()函数移动跟x轴和轴相符的边框,使其穿过原点(0,0)
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))
添加公式注释
-
用注释和箭头(可选)明曲线上某一数据点的位置,这一功能非常有用。例如,可以用 LaTeX表达式作为注释,比如添加表示x趋于0时函数 sinx/x的极限的公式。
-
matplotlib库的 annotate()函数特别适用于添加注释。虽然它有多个关键字参数,这些参数可改善显示效果,但是参数设置略显繁琐,也就使得 annotate()函数看似有些麻烦。
-
第一个参数为含有 LaTex表达式、要在图形中显示的字符串;
-
随后是各种关键字参数。注释在图表中的位置用存放数据点[x,y]坐标的列表来表示,需把它们传给xy关键字参数。
-
文本注释跟它所解释的数据点之间的距离用xytext关键字参数指定,用曲线箭头将其表示出来。
-
箭头的属性则由arrowprops关键字参数指定。
plt.annotate(r'$lim_{x o 0}frac{sin()}{x}= 1$', xy=[0, 1], xycoords='data',
xytext=[30, 30], fontsize=16, textcoords='offset points', arrowprops=dict(arrowstyle="->",
connectionstyle="arc, rad= 2"))
为pandas数据绘制线形图
-将DataFrame中的数据做成线性图表很简单,只需把 DataFrame作为参数传入plot()函数,就能得到多序列线性图。
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
data = {
'series1':[1,3,4,3,5],
'series2':[2,4,5,2,4],
'series3':[3,2,3,1,3]}
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()
直方图
-
pyplot用于绘制直方图的函数为hist(),该函数具有一个其他绘图函数所没有的功能。它除了绘制直方图外,还以元组形式返回直方图的计算结果。事实上,hist()函数还可以实现直方图的计算。也就是说,它能够接收一系列样本个体和期望的面元数量作为参数,会把样本范围分成多个区间(面元),然后计算每个面元所包含的样本个体的数量。运算结果除了以图形形式表示外,还能以元组形式返回。
-
例子
pop = np.random.randint(0,100,100)
n,bins,patches = plt.hist(pop,bins=20)
plt.show()
条状图
- x轴表示的不是数值而是类别。用 matplotlib的bar()函数生成条状图很简单。
index = [0,1,2,3,4]
values = [5,7,3,4,6]
plt.bar(index,values)
plt.show()
- 由于每个长条对应的是一种类别,最好用刻度标签标明其类别,方法是把表示各个类别的字符串传递给 xticks()参数。
index = np.arange(5)
values = [5,7,3,4,6]
plt.bar(index,values)
plt.xticks(index,['A','B','C','D','E'])
plt.show()
-
还可以借助很多其他步骤进一步改进条状图。每一种改进方法都是通过在bar()函数中添加特定的关键字参数来实现的。
-
例如,把包含标准差的列表传给yerr关键字参数,就能添加标准差。这个参数常跟error_kw参数一起使用,而后者又接收其他可用于显示误差线的关键字参数。
-
常用的两个是 eColor和 capsize, eColor指定误差线的颜色,而 capsize指定误差线两头橫线的宽度。
-
还有一个参数叫作 alpha,它控制的是彩色条状图的透明度。 alpha的取值范围为0-1。0表示对象完全透明,随着alpha值的增加,对象逐渐清晰起来,到1时,颜色显示全了。
-
带有误差线的条状图
index = np.arange(5)
values = [5,7,3,4,6]
std1 = [0.8,1,0.4,0.9,1.3]
plt.title('A bar Chart')
plt.bar(index,values,yerr=std1,error_kw={'ecolor':'0.1',
'capsize':6},alpha=0.7,label='First')
plt.xticks(index,['A','B','C','D','E'])
plt.show()
水平条状图
- 实际上还有水平方向的条状图。这种模式的条状图用barh()函数实现。bar()函数的参数和关键字参数对该函数依然有效。唯一需要注意的是,两条
轴的用途跟垂直条状图刚好相反。水平条状图中,类别分布在轴上,数值显示在x轴。
index = np.arange(5)
values = [5,7,3,4,6]
std1 = [0.8,1,0.4,0.9,1.3]
plt.title('A Horizontal bar Chart')
plt.barh(index,values,xerr=std1,error_kw={'ecolor':'0.1',
'capsize':6},alpha=0.7,label='First')
plt.yticks(index,['A','B','C','D','E'])
plt.show()
多序列条状图
- 把每个类别占据的空间(方便起见,宽度为1)分为多个部分。想显示几个长
条,就将其分为几部分。建议再增加一个额外的空间,以便区分两个相邻的类别。
index = np.arange(5)
values1 = [5,7,3,4,6]
values2 = [6,6,4,5,7]
values3 = [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,values1,bw,color='b')
plt.bar(index+bw,values2,bw,color='g')
plt.bar(index+2*bw,values3,bw,color='r')
plt.xticks(index+1.5*bw,['A','B','C','D','E'])
plt.show()
- 多序列水平条状图的生成方法也很简单。用barh()函数替换bar()函数,同时 ticks()函数替换为xticks()函数。此外,还需要交换axis()函数的参数中两条轴的取值范围。
index = np.arange(5)
values1 = [5,7,3,4,6]
values2 = [6,6,4,5,7]
values3 = [5,6,5,4,6]
bw = 0.3
plt.axis([0,8,0,5])
plt.title('A Multiseries Bar Chart',fontsize=20)
plt.barh(index,values1,bw,color='b')
plt.barh(index+bw,values2,bw,color='g')
plt.barh(index+2*bw,values3,bw,color='r')
plt.yticks(index+1.5*bw,['A','B','C','D','E'])
plt.show()
为pandas DataFrame绘制堆积条状图
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()
其他条状图
-
另外一种非常有用的图形表示法是用条状图表现对比关系。两列有着共同类别的数据,其条状图形分列于x轴两侧,沿y轴方向生长。
-
要生成这类图形,需事先对其中一个序列的y值进行取相反数操作
-
如何修改条状图的边框和条状图内部区域的颜色。其实,只要用另外两个关键字参数 facecolor和 edgecolor设置两种不同的颜色即可。
-
如何在每个长条的末端显示ν值标签,这有助于增强条状图的可读性。可以使用for循环,在循环体内再借助text()函数显示y值标签。标签的位置可用ha和va关键字参数来调整,它们分别控制着标签在水平和垂直方向上的对齐效果。
x0 = np.arange(8)
y1 = np.array([1,3,4,6,4,3,2,1])
y2 = np.array([1,2,3,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()
饼图
-
饼图也可以用来表示数据。用pie(函数制作饼图很简单。
-
该函数仍然以要表示的一列数据作为主要参数。这里直接选用百分比(总和为100),可以选用每种类别的实际数值,而让pie(函数自己去计算每个类别所占的比例。
-
对于这类图表,仍需用关键字参数设置关键特征。例如,若要定义颜色列表,为作为输入的数据序列分配颜色,可使用 colors关键字参数,把颜色列表赋给它。另外一个重要的功能是为饼图的每一小块添加标签,为此需使用 labels关键字参数,把标签列表赋给它。此外,为了绘制标准的圆形饼图,还需要在代码最后调用axis()函数,用字符串' equal'作为参数。
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()
- 为了增强饼图的表现力,还可以制作从圆饼中抽取出一块的效果。要突出显示 Nokia这一块,则需要使用 explode关键字参数。它的数据类型为浮点型,取值范围为0~1。1表示这一块完全脱离饼图;0表示没有抽取,也就是饼图仍
然是一个完整的圆;而0~1的值则表示这一块未完全脱离饼图。
- 可以用 title(函数为饼图添加标题。还可以用 Istartangle关键字参数调整饼图的旋转角度,该参数接收一个0-360的整数,表示转换的角度(默认值为0)。
labels=['Nokia','Samsung','Apple', 'Lumia']
values=[10,30,45,15]
colors=['yellow','green','red', 'blue']
explode = [0.3,0,0,0]
plt.title('A Pie Chart')
plt.pie(values,labels=labels,colors=colors,explode=explode,startangle=180)
plt.axis('equal')
plt.show()
-
用autopct关键字参数,在每一块的中间位置添加文本标签来显示百分比。
-
可以用 shadow关键字参数添加阴影效果,将其置为True即可
plt.pie(values,labels=labels,colors=colors,explode=explode,startangle=180,shadow=True,autopct='%1.1f%%')
为DataFrame绘制饼图
data = { 'series1':[1,3,4,3,5],
'series2':[2,4,5,2,4],
'series3':[3,2,3,1,3]}
df = pd.DataFrame(data)
df['series1'].plot(kind='pie',figsize=(6,6))
plt.show()
高级图表
等值线图
-
等值线图或等高线图在科学界很常用。这种可视化方法用由一圈圈封闭的曲线组成的等值线图表示三维结构的表面,其中封闭的曲线表示的是一个个处于同一层级或z值相同的数据点。虽然等值线图看上去结构很复杂,其实用 matplotlib实现起来并不难。首先,你需要用z=f(xy)函数生成三维结构。然后,定义x、y的取值范围,确定要显示的区域。之后使用(xy)函数计算每一对(xy)所对应的z值,得到一个z值矩阵。最后,用 Contour()函数生成三维结构表面的等值线图。
-
定义颜色表,为等值线图添加不同颜色,效果往往会更好;也就是说,用渐变色填充由等值线划分成的区域。
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,color='black')
plt.contourf(X,Y,f(X,Y),8)
plt.clabel(C,inline=1,fontsize=10)
plt.show()
-
cmap关键字参数决定了颜色的种类
-
colorbar()函数增加图例作为对图表中所用颜色的说明
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,color='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,θ),是在坐标轴系中表示数据的另一种方法。
-
自定义任意的颜色列表,方法是指定颜色列表,其中每个元素为字符
串类型的RGB编码,其格式为#rrggbb
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","#EAAA28","#579575",'#839557',"#958c12",
'#953579',"#4b5de4"])
bars = plt.bar(theta,radii,width=(2*np.pi/N),bottom=0.0,color=colors)
plt.show()
- 虽然定义了一列#rggb格式的颜色值,其实还可以用颜色的实际名称来表示颜色。
colors =np.array(['lightgreen', 'darkred','navy','brown','violet','plum',
'yellow','darkgreen'])
mplot3d
- plot3d工具集是 matplotlib内置的标配,可用来实现3D数据可视化功能。如果生成的图形在单独的窗口中显示,你还可以用鼠标旋转三维图形的轴进行查看。
plot3d仍然使用 Figure对象,只不过Axes对象要替换为该工具集的Axes3D对象。因此,使用Axes30对象前,需先将其导入进来。
from mpl_toolkits.mplot3d import Axes3D
3D曲面
- 绘制等值线图所用到的z=f(x,y)函数。计算出分割线坐标后,就可以用
plot_surface()函数绘制曲面。
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()
- 修改颜色表,3D表面效果会更加突出,例如,可以用cmap关键字参数指定各颜色。还可以用view_init()函数旋转曲面,修改e1ev和azim两个关键字参数,从不同的视角查看曲面,其中第一个关键字参数指定从哪个高度查看曲面,第二个参数指定曲面旋转的角度.
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散点图
-
通过这种可视化方法,能够识别数据点的分布是否遵循某种特定趋势,尤其是可以识别它们是否有聚集成簇的趋势。
-
下面这个例子中,我们仍旧使用 scatter()函数,使用方法跟绘制2D图形相同,但是要将其应用于AXes3D对象。这样做,你可以多次调用scatter()函数,在同一个3D对象中显示不同的序列。
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_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.show()
3D条状图
- 要绘制这种图表,同样是将bar()函数应用于AXes3D对象。如果定义了多个序列,可以在同一个3D对象上多次调用bar()函数。
x = np.arange(8)
y = np.random.randint(0,10,8)
y2 = y + np.random.randint(0,10,8)
y3 = y2 + np.random.randint(0,10,8)
y4 = y3 + np.random.randint(0,10,8)
y5 = y4 + np.random.randint(0,10,8)
clr = ['#4bb2c5',"#c5b47f","#EAAA28",
"#579575",'#839557',"#958c12", '#953579',"#4b5de4"]
fig = plt.figure()
ax = Axes3D(fig)
ax.bar(x,y,0,zdir='y',color=clr)
ax.bar(x,y2,10,zdir='y',color=clr)
ax.bar(x,y3,20,zdir='y',color=clr)
ax.bar(x,y4,30,zdir='y',color=clr)
ax.bar(x,y5,40,zdir='y',color=clr)
ax.set_xlabel('X Axis')
ax.set_ylabel('Y Axis')
ax.set_zlabel('Z Axis')
ax.view_init(elev=40)
plt.show()
多面板图形
在其他子图中显示子图
- 主Axes对象(也就是说主图表)跟放置另一个Aes对象实例的框架分开。用 figure()函数取到 Figure对象,用 add axes()函数在它上面定义两个Axes对象。
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()
子图网络
- 要把图形分成多个区域,添加多个子图,可以用 subplots(函
数,方法也很简单。 matplotlib的 Gridspec()函数可用来管理更为复杂的情况。它把绘图区域分成多个子区域,你可以把一个或多个子区域分配给每一幅子图。
gs = plt.GridSpec(3,3)
fig = plt.figure(figsize=(6,6))
fig.add_subplot(gs[1,:2])
fig.add_subplot(gs[0,:2])
fig.add_subplot(gs[2,0])
fig.add_subplot(gs[:2,2])
fig.add_subplot(gs[2,1:])
plt.show()
- 可以在 add subplot()函数返回的Axes对象上调用plot()函数,绘制相应的图形。
gs = plt.GridSpec(3,3)
fig = plt.figure(figsize=(6,6))
x1 = np.array([1,3,2,5])
y1 = np.array([4,3,7,2])
x2 = np.arange(5)
y2 = np.array([3,2,4,6,4])
s1 = fig.add_subplot(gs[1,:2])
s1.plot(x1,y1,'r')
s2 = fig.add_subplot(gs[0,:2])
s2.bar(x2,y2)
s3 = fig.add_subplot(gs[2,0])
s3.barh(x2,y2,color='g')
s4 = fig.add_subplot(gs[:2,2])
s4.plot(x2,y2,'k')
s5 = fig.add_subplot(gs[2,1:])
s5.plot(x1,y1,'b',x2,y2,'yo')
plt.show()