本章探索
*线样式自定义
*点样式自定义
*轴刻度自定义
*Matplotlib中可用的多种图类型,比如直方图(histograms)、条形图(bars)、错误条形图(errorbars)、圆形分隔统计图表(pie charts)、散点图(scatter plots)等等。
*极坐标图(Polar charts)
*在我们的图中插入文本信息
标记和线样式(Markers and line styles)
plt.plot(X, Y, '<format>', ...)
Colors、Line styles、Marker styles可以定制。
控制颜色
In [34]: import matplotlib.pyplot as plt
In [35]: import numpy as np
In [36]: y=np.arange(1,3)
In [37]: plt.plot(y,'y')
Out[37]: [<matplotlib.lines.Line2D at 0x20e7962cb00>]
In [38]: plt.plot(y+1,'m')
Out[38]: [<matplotlib.lines.Line2D at 0x20e7b0de470>]
In [39]: plt.plot(y+2,'c')
Out[39]: [<matplotlib.lines.Line2D at 0x20e7b0e45f8>]
In [40]: plt.show()
确定多线图样式
plot()句法可做如下拓展:
plt.plot(x1,y1,fmt1,x2,y2,fmt2,...)
In [45]: import matplotlib.pyplot as plt
In [46]: import numpy as np
In [47]: y=np.arange(1,3)
In [48]: plt.plot(y,'y',y+1,'m',y+2,'c')
控制线样式
In [49]: import matplotlib.pyplot as plt
In [50]: import numpy as np
In [51]: y = np.arange(1,3)
In [52]: plt.plot(y,'--',y+1,'-.',y+2,':')
Out[52]:
[<matplotlib.lines.Line2D at 0x20e749fb550>,
<matplotlib.lines.Line2D at 0x20e749fb6a0>,
<matplotlib.lines.Line2D at 0x20e749fb7f0>]
In [53]:
控制标记样式
In [53]: import matplotlib.pyplot as plt
In [54]: import numpy as np
In [55]: y=np.arange(1,3,0.2)
In [56]: plt.plot(y,'x',y+0.5,'o',y+1,'D',y+1.5,'^',y+2,'s')
Out[56]:
[<matplotlib.lines.Line2D at 0x20e7964d978>,
<matplotlib.lines.Line2D at 0x20e7964d320>,
<matplotlib.lines.Line2D at 0x20e7964d630>,
<matplotlib.lines.Line2D at 0x20e7962c320>,
<matplotlib.lines.Line2D at 0x20e7962c908>]
In [57]:
In [57]: import matplotlib.pyplot as plt
In [58]: import numpy as np
In [59]: y=np.arange(1,3,0.3)
InIn [60]: plt.plot(y,'cx--',y+1,'mo',y+2,'kp-.');
使用关键字参数的更优控制(Finer control with keyword arguments)
格式化字符串真正有用,但是它们有一些缺陷。例如,不允许我们针对线条和标记确定不同颜色,如我们在前面例子中见到的。
plot()真正是一个丰富的函数,这有许多关键字参数来配置颜色、标记和线条样式。
------------------------------------------------------------------------------------
Keyword argument Description
------------------------------------------------------------------------------------
Color or c 设置线条颜色;接受任何Matplotlib颜色格式
linestyle 设置线条样式;接受前面见到的线条样式
linewidth 设置线条宽度了接受点的浮点值
marker 设置线条标记样式
markeredgecolor 设置标记边沿颜色;接受任何Matplotlib颜色格式
markerfacecolor 设置标记面部颜色;接受任何Matplotlib颜色格式
markersize 以点的方式设置标记大小;接受浮点值
------------------------------------------------------------------------------------
In [1]: import matplotlib.pyplot as plt
In [2]: import numpy as np
In [3]: y = np.arange(1,3,0.3)
In [4]: plt.plot(y,color='blue',linestyle='dashdot',linewidth=4,marker='o',markerfacecolor='red',markeredgecolor='black
...: ',markeredgewidth=3,markersize=12);
In [5]: plt.show()
前面的屏幕截图不是Matplotlib可以生成的最佳图形,但是它展示了我们手头上许多配置选项。
另一个关键字参数提供的可能性是如果我们画多线图,参数应用于他们所有之中。我们想要画两条绿线,我们可以调用:
plt.plot(x1,y1,x2,y2,color='green')
颜色属性同时应用于这两条线。
这有许多针对标记和线样式的实验,你的想象力是唯一限制。
处理X和Y刻度
我们已经看到在每幅图中的X和Y刻度,但是我们还没有注意到他们明确存在。
垂直和水平刻度是坐标轴上的小段,经常与轴标签耦合使用,用于提供图形上的参考系统。
Matplotlib提供两个基本的函数来管理他们---xticks()和yticks().
参数(表单列表)可以传给函数的是:
*刻度的位置
*画这些位置的标号
用一个例子解释:
In [8]: import matplotlib.pyplot as plt
In [9]: x = [5,3,7,2,4,1]
In [10]: plt.plot(x);
In [11]: plt.xticks(range(len(x)),['a','b','c','d','e','f']);
In [12]: plt.yticks(range(1,8,2));
In [13]: plt.show()
在这个代码片段,我们使用xticks()来明确位置和标号,yticks()仅显示奇数位置的刻度。
图类型(Plot types)
直方图(Histogram charts)
Matplotlib称直方图为bins。
我们将使用NumPy random.randn()来获取高斯分布中的随机数数组,然后使用hist()函数以直方图格式画出来。
In [14]: import matplotlib.pyplot as plt
In [15]: import numpy as np
In [16]: y = np.random.randn(1000)
In [17]: plt.hist(y);
In [18]: plt.show()
hist()默认使用bins值10.
hist(y, <bins>)
In [19]: plt.hist(y,25);
In [20]: plt.show()
错误条形图(Error bar charts)
真实值附近 around the true value
errorbar()函数
例子:
In [21]: import matplotlib.pyplot as plt
In [22]: import numpy as np
In [23]: x = np.arange(0,4,0.2)
In [24]: y=np.exp(-x)
In [25]: e1=0.1 * np.abs(np.random.randn(len(y)))
In [26]: plt.errorbar(x,y,yerr=e1,fmt='.-');
In [27]: plt.show()
In [21]: import matplotlib.pyplot as plt
In [22]: import numpy as np
In [23]: x = np.arange(0,4,0.2)
In [24]: y=np.exp(-x)
In [25]: plt.errorbar(x,y,xerr=e1,fmt='.-');
In [26]: plt.show()
注意,对于行,我们使用一个定制的格式,由fmt参数确定。有趣的格式化参数有:
*fmt:这是线条图形格式。如果为None,仅画出没有线条连接他们的错误条形图。
*ecolor:这接受任何的Matplotlib颜色,确定错误星条的颜色。如果为None,使用标记颜色。
*elinewidth:这确定错误条形图的线条宽度。如果为None,使用线条宽度。
*capsize:这确定以像素表示的错误星条图的帽子的大小。
同时使用xerr和yerr:
In [31]: import numpy as np
In [32]: x = np.arange(0,4,0.2)
In [33]: y=np.exp(-x)
In [34]: e1=0.1*np.abs(np.random.randn(len(y)))
In [35]: e2=0.1*np.abs(np.random.randn(len(y)))
In [36]: plt.errorbar(x,y,yerr=e1,xerr=e2,fmt='.-',capsize=0);
In [37]: plt.show()
上图是对称错误星条图(symmetrical error bars),每个点有4个不同的错误,以及每个对应一个方向:-x,+x,-y和+y。
下面介绍非对称错误星条图(asymmetrical error bars)
In [38]: import matplotlib.pyplot as plt
In [39]: import numpy as np
In [40]: x = np.arange(0,4,0.2)
In [41]: y=np.exp(-x)
In [42]: e1=0.1*np.abs(np.random.randn(len(y)))
In [43]: e2=0.1*np.abs(np.random.randn(len(y)))
In [44]: plt.errorbar(x,y,yerr=[e1,e2],fmt='.-');
In [45]: plt.show()
在上面代码片段中,-y是e1,+y是e2。
条形图
条形图显示矩形条(垂直或者水平),其长度与表示的值成比例。他们一般用于形象地比较两个或多个值。
Matplotlib中,bar()函数用做生成星条图。该函数期望两列值的列表:X轴坐标,即星条图左边沿的位置以及星条图的高度。
In [46]: import matplotlib.pyplot as plt
In [47]: plt.bar([1,2,3],[3,2,5]);
In [48]: plt.show()
从上面屏幕截图可见,左边沿起点由第一个列表确定,其高度是第二个列表的值。
Matlibplot设置,条形图宽度默认0.8,(width也是默认关键字参数,用来改变该值),因此我们看见漂亮的分离星条图。如往常,每样东西都是刻度化的,以及自动调整来完美适应图形区域。
可以说星条图是包含在以左底角为起点的一个箱子中的,并由第一个列表明确确定,高度由第二个列表的值确定。星条图的宽度要么是默认值,或者是由width参数确定的。
简要重述箱子的维度:
从left或者bottom---left,left+height,left+height+width,left+width。
大部分有用的关键字参数列表如下:
- width: 星条图宽度
- color: 星条图颜色
- xerr,yerr:星条图表上的错误星条(是的,bar()支持错误星条)
- bottom:星条图底部坐标
下面看一个从字典创建一个条形图例子。我们将使用字典值作为条形图的高度,并作为yticks()的参数,而字典键值用做xtick()的位置和条形图的标签。
import matplotlib.pyplot as plt
import numpy as np
dict = {'A':40,'B':70,'C':30,'D':85}
for i, key in enumerate(dict):plt.bar(i,dict[key]);
plt.xticks(np.arange(len(dict))+0.4,dict.keys());
plt.yticks(dict.values());
plt.show()
import matplotlib.pyplot as plt
import numpy as np
data1=10*np.random.rand(5)
data2=10*np.random.rand(5)
data3=10*np.random.rand(5)
e2=0.5*np.abs(np.random.randn(len(data2)))
locs=np.arange(1,len(data1)+1)
width=0.27
plt.bar(locs,data1,width=width);
plt.bar(locs+width,data2,yerr=e2,width=width,color='red');
plt.bar(locs+2*width,data3,width=width,color='green');
plt.xticks(locs+width*1.5,locs);
plt.show()
在前面的屏幕快照,我们可以看到条形组的颜色有蓝色、红色和绿色(通常顺序),但错误条形的颜色是蓝色(这里是黑色,原因待研究)。
注意width变量的使用:首先,我们使用这个来明确每个条形的宽度是一样的,然后让随后的条形序列以width的倍数开始(这样前面的条形结束,当前的条形开始,将条形打包在一起);最后,我们使用width来放置xticks到“三个条形组”的中间--1.5的倍数,我们获得这个值来座位组的中间。
Matplotlib提供的另外一个类似函数是barh()-画垂直条形图(不是水平的,如bar()那样)。此外,还有其他类型的条形图(up or down,stacked,candlestick bars等等)。
饼图(Pie charts)
饼图是循环表示的,分成扇区(wedges).每个扇区的弧长(arc length)是与我们描述的数量成比例的。这是一种有效表示信息的方式,当我们主要感兴趣的是比较楔子与整个饼,而不是楔子之间比较。
Matplotlib提供函数pie()来根据数组X画饼图。楔子(wedges)是成比例创建的,这样数组X中的每个值x产生一个与x/sum(X)成比例的楔子。
注意,如果sum(X)小于1,那么饼图使用X值直接画,且不做任何限制,最后形成一个不连续的饼。
饼图看上去最佳,如果图形和坐标轴是以平方的格式(如果不是,用普通的矩形图,看起来像椭圆)。
In [101]: import matplotlib.pyplot as plt
In [102]: plt.figure(figsize=(3,3));
In [103]: x=[45,35,20]
In [104]: labels=['Cats','Dogs','Fishes']
In [105]: plt.pie(x,labels=labels);
In [106]: plt.show()
上图可见饼图颜色递进是蓝色、绿色、红色。
数组X的总和是100,但是我们可以针对楔子明确指定任何值,Matplotlib将会根据这些值来适应这个饼图。
这有一些有趣的关键字参数,我们可以用来定制饼图。
- explode :如果指定,它是一个与X一样的数组。
- colors: 这是一个Matplotlib颜色列表,循环地给楔子涂颜色。
- labels,labeldistance:这是标签列表,X值得每个对应一个。labeldistance是画标签的径向距离。
- autopct,pctdistance:这种格式字符串或者函数用于标签楔子带数字值。pctdstance是饼图中间和文本开始之间的比例。
- shadow:这为楔子或者饼图画阴影。
In [108]: import matplotlib.pyplot as plt
In [109]: plt.figure(figsize=(3,3));
In [110]: x=[4,9,21,55,30,18]
In [111]: labels=['Swiss','Austria','Spain','Italy','France','Benelux']
In [112]: explode=[0.2,0.1,0,0,0.1,0]
In [113]: plt.pie(x,labels=labels,explode=explode,autopct='%1.1f%%');
In [114]: plt.show()
上面饼图的颜色递进关系:蓝色、绿色、红色、蓝绿色、洋红色、黄色。我们可以看到,楔子是从水平坐标轴画的,从右边开始,逆时针移动。
分散图(Scatter plots)
分散图显示两组数据值。数据可视化由点的集合而不是连线完成。每个点的坐标由变量值确定(一个变量确定X轴,另一个变量确定Y轴)。
分散图用于确定两个变量之间的潜在关联,经常在工作于拟合回归函数之前画出。它给出一个好的可视图片的关联性,特别对于非线性关系。
Matplotlib提供scatter()函数来画X versus Y的与分散图同样长度的一维数组(所以这里搜索不到相关性)。
In [115]: import matplotlib.pyplot as plt
In [116]: import numpy as np
In [117]: x=np.random.randn(1000)
In [118]: y=np.random.randn(1000)
In [119]: plt.scatter(x,y)
Out[119]: <matplotlib.collections.PathCollection at 0x17e1c1cf5c0>
In [120]: plt.show()
采用下面的一些关键字参数来装饰图表:
-
s: 这代表以pixel*pixel标记的大小。可为单个值(用于所有点)或者一组相同的X和Y的大小。(这样每个点都有自己的大小)
*c: 这是点的颜色。它可以是单个值或者颜色列表(绘制的点中循环)最终是X和Y相同的大小。这些值可以是Matplotlib颜色编码或者甚至是采用颜色映射映射到颜色的数字。
*marker: 这确定标记用于画点;可用值如下:
In [122]: size=50*np.random.randn(1000)
In [123]: colors=np.random.rand(1000)
In [124]: plt.scatter(x,y,s=size,c=colors);
c:\python36\lib\site-packages\matplotlib\collections.py:857: RuntimeWarning: invalid value encountered in sqrt
scale = np.sqrt(self._sizes) * dpi / 72.0 * self._factor
In [125]: plt.show()
c:\python36\lib\site-packages\matplotlib\collections.py:857: RuntimeWarning: invalid value encountered in sqrt
scale = np.sqrt(self._sizes) * dpi / 72.0 * self._factor
极坐标图(Polar charts)
polar() Matplotlib函数画极坐标图。其参数是两个列表(长度相同)---theta对应角度坐标,r对应径向坐标。
In [126]: import matplotlib.pyplot as plt
In [127]: import numpy as np
In [128]: theta=np.arange(0.,2.,1./180.)*np.pi
In [129]: plt.polar(3*theta,theta/5);
In [130]: plt.polar(theta,np.cos(4*theta));
In [131]: plt.polar(theta,[1.4]*len(theta));
In [132]: plt.show()
极坐标图的导航工具栏
pan()和zoom()函数
控制半径和角度网格
rgrid()
thetadrid()
rgrids()
我们可以传递的参数:
radii:网格线可画的径向距离。
labels:在radii网格显示的标签。
angle:标签显示的角度(默认22.5度)。
In [133]: import matplotlib.pyplot as plt
In [134]: import numpy as np
In [135]: theta=np.arange(0.,2.,1./180.)*np.pi
In [136]: r=np.abs(np.sin(5*theta)-2.*np.cos(theta))
In [137]: plt.polar(theta,r);
In [138]: plt.thetagrids(range(45,360,90));
In [139]: plt.rgrids(np.arange(0.2,3.1,.7),angle=0);
In [140]: plt.show()
图片、注释和箭头中的文本
图片中的文本
xlabel()
ylabel()
title()
text()函数---在任意一个位置写一个字符串(text):
plt.text(x,y,text)
画sine函数图,添加注释说明sin(0)等于0.
In [141]: import matplotlib.pyplot as plt
In [142]: import numpy as np
In [143]: x=np.arange(0,2*np.pi,.01)
In [144]: y=np.sin(x)
In [145]: plt.plot(x,y)
Out[145]: [<matplotlib.lines.Line2D at 0x17e15a31860>]
In [146]: plt.text(0.1,-0.04,'sin(0)=0');
In [147]: plt.show()
注释
annotate()函数提供功能来让注释容易。在一个注释中,我们不得不考虑两点-我们想要注释的图片要点(由一个xy关键字参数表示的)和我们要放置注释文本位置的图片位置(由xytext表示)。他们都以数据坐标位置(x,y)格式表示。
此外,这有一个额外的参数来明确箭头特性,那就是text()和annotate()的功能差异。我们用箭头连接注释文本到注释要点。
In [1]: import matplotlib.pyplot as plt
In [2]: y=[13,11,13,12,13,10,30,12,11,13,12,12,12,11,12]
In [3]: plt.plot(y);
In [4]: plt.ylim(ymax=35);
In [5]: plt.annotate('this spot must really\nmeansomething',xy=(6,30),xytext=(8,31.5),arrowprops=dict(facecolor='black'
...: ,shrink=0.05));
In [6]: plt.show()
注意关于缩放(shrink)特性。
一些有趣的参数是:
*width: 点的箭头宽度。
*frac: 箭头碎片头部占用的长度。
*headwidth:点的箭头基本宽度。
*shrink:(0.05=5%)
箭头(Arrows)
箭头起点(x,y),箭头终点(x+dx,y+dy)。
plt.arrow(x,y,dx,dy)
很不幸,这个函数相当难用。
plt.anotate("",...)