title: matplotlib 外观和基本配置笔记
notebook: Python
tags:matplotlib
---
参考资料,如何使用matplotlib绘制出数据图形,参考另一篇matplotlib绘制多种图形笔记
- 通过在python GUI中,新建一个文件,并且可以运行(非常似Matlab)。执行文件就会批量执行绘图命令,这样就在学习matplotlib的过程中可以尝试修改几个小参数。
- 这些知识掌握以后,还需要学习pylab这个模块和IPython
绘制函数曲线
figure()
matplotlib.pyplot.figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, frameon=True, FigureClass=
parameter keyword | parameter value |
---|---|
num | integer or string. 如果缺省, 那么自动增加fig num; 如果 fig num已存在,则激活那个figure, 并且返回(对于其他parameter,可能修改这个figure 的相应属性) |
figsize | (width, height) |
facecolor | the figure's whole background color; 比如图表中折线图范围外的部分,就是背景 |
bordercolor | 不经常使用 |
通常,在pyplot.figure(...,...)
和pyplot.show()
之间的pyplot语句都是画在一张图上面的。
如果没有调用pyplot.figure(...,...)
语句,那么pyplot.plot(), pyplot.show()
语句就是另外新建了一个figure。
plot()绘曲线
matplotlib.pyplot.plot(*args, **kwargs)
plot()函数有很多参数项,分为
Axes.args
类参数项
args参数可以多个 \(x,y\) 变量对kwargs
类参数项
kwargs参数项 表示了Line2D
对象的属性,参数项可以表示很多Line2D
的属性,每个参数项可以用 parameter keyword = "parameter value"的形式表示,常用的参数项是:- label: 此名字在图示(legend)中显示。只要在字符串前后添加"$"符号,matplotlib就会使用其内嵌的latex引擎绘制的数学公式
- marker, markersize, markerfacecolor, markeredgecolor
- color, linewidth
url, visible
注意:label这个属性,在调用
pyplot.legend()
后显示在图示里面
各属性的可选参数值参考
- 在
pyplot.plot()
中可以画出多条曲线- 多个参数
- 使用
pyplot.plot(x1, y1, 'g^', x2, y2, 'g-')
不同形式的曲线 - 使用
pyplot.plot(x1, y1, x2, y2, 'g-')
则相同形式的曲线
- 使用
- 先调用
pyplot.figure()
再多次调用pyplot.plot(*args, **kwargs)
这样每条曲线可以设置很多Line2D的属性,比如label
- 多个参数
给曲线设置属性,如果pyplot.plot()方法不能全部设置外观属性,那么可以通过 先分配对象,再设置属性的办法 绘图
line = plt.plot(x, x * x) line.set_antialiased(False)
lines = plt.plot(x, np.sin(x), x, cos(x)) plt.setp(lines, color = "r", linewidth = 2.0)
xlabel(), ylabel(), title()
legend()
pyplot.plot()
和pyplot.legend()
搭配使用- 在使用
pyplot.subplot()
情形时,就是pyplot.subplot()
和pyplot.legend()
搭配使用
subplot()绘制多轴图
一个绘图对象(figure)可以包含多个轴(axis),在Matplotlib中用轴表示一个绘图区域,可以将其理解为子图(即axes属性中有多个实例)
pyplot.subplot(numRows, numCols, plotNum)
subplot将整个绘图区域等分为numRows
行 * numCols
列个子区域,然后按照从左到右,从上到下的顺序对每个子区域进行编号,左上的子区域的编号为1
如果希望某个轴占据整个行或者整个列的话,可以如下调用:
plt.subplot(2,2,1)
plt.subplot(2,2,2)
plt.subplot(2,1,2)
xlim(), ylim()
显示X轴/Y轴的范围
注: 在显示图中, 左下角有一些鼠标可以选的选项,比如"左右拖动曲线"
参数设置
matplotlib.rcParams["savefig.dpi"]
可以查看保存图像的像素设置- rcParams 是一个字典变量,保存了绘图配置的各个选项的“关键字:参数值”对
- 通过rc_params() 来读取配置文件,结果保存在rcParams字典中
- 修改raParams字典中个别选项使用matplotlib.rc([keyword = "parameter value"]*)的方式
- 修改了rcParams后,重置rcParams时,matplotlib.rcdefaults()
- 修改了配置文件后,更新rcParams时,matplotlib.rcParams.update(matplotlib.rc_params)
绘制一般的数据图(直方图/散点图/圆形图)
Figure
一般示例程序中都直接采用了`pyplot.subplot()和pyplot.axes()的方法,不过在我程序时,使用
fig = plt.figure(), fig.add_subplot(), fig.add_axes()`的流程
参考User Guide,翻译如下:
Figure图表包括组成图标的所有元素,Figure对象有如下属性包含其它的Artist对象:
attribute name | type | 介绍 |
---|---|---|
patch | Rectangle | 作为背景的 Rectangle 对象 |
axes | list of Axes | Axes对象列表 |
images | list of FigureImage | FigureImage 对象列表,用来显示图片 |
legends | list of Legend | Legend 对象列表 |
lines | list of Line2D | Line2D对象列表 |
texts | list of Text | Text对象列表,用来显示文字 |
最大的Artist容器是matplotlib.figure.Figure,它包括组成图表的所有元素。图表的背景是一个Rectangle对象,用Figure.patch属性表示。当你通过调用add_subplot或者add_axes方法往图表中添加轴或子图(实际轴就是子图时),这些子图都将添加到Figure.axes属性中,同时这两个方法也返回添加进axes属性的对象,注意返回值的类型有所不同,实际上AxesSubplot是Axes的子类。
为了支持pylab中的gca()等函数,Figure对象内部保存有当前轴的信息,因此不建议直接对Figure.axes属性进行列表操作,而应该使用add_subplot, add_axes, delaxes等方法进行添加和删除操作。但是使用for循环对axes中的每个元素进行操作是没有问题的,下面的语句打开所有子图的栅格。
- 上表中的属性,是直接
fig.lines
、fig.images
这样调用的,由于lines
、images
这几个属性都是list类,那么可以使用list类的函数,如下:
>>> from matplotlib.lines import Line2D
>>> fig = plt.figure()
>>> line1 = Line2D([0,1],[0,1], transform=fig.transFigure, figure=fig, color="r")
>>> line2 = Line2D([0,1],[1,0], transform=fig.transFigure, figure=fig, color="g")
>>> fig.lines.extend([line1, line2])
>>> fig.show()
- 不过,要使用add_subplot()和add_axes()增加子图
add_subplot(*args,**kwargs)
fig.add_subplot(*args,**kwargs)
的参数,和pyplot.subplot(*args,**kwargs)
的参数是相似的用法,如:fig.add_subplot(2,1,1)
fig.add_subplot(2,1,1, facecolor = 'r')
fig.add_subplot(sub)
----kwargs参数- kwargs是Axes对象
add_axes(*args,**kwargs)
fig.add_axes(*args,**kwargs)
的参数,和pyplot.axes(*args,**kwargs)
的参数是相似的用法args
是[left,bottom,width,height]
,每个参数都是小数,表示在图片中的相对比例(位置/长度),如:
fig.add_axes([0.1,0.1,0.5,0.5])
, 其中用rect 表示[0.1,0.1,0.5,0.5]
多次使用这样的语句可以在一个子图上叠加另一个子图- 注意,rect的参数含义是left, bottom, width, height,是定好左下角坐标后的相对大小;
- args 参数的作用像
pyplot.figure
的num变量的作用,可以标识一个子图。当fig.add_axes(rect)
中的rect在fig中已经存在时,fig.add_axes(rect)
会返回已存在的那个子图。如果想在原位置覆盖一个新子图,要使用语句fig.add_axes(rect, label='axes1)和fig.add_axes(rect, label='axes2')
,通过不同的label
关键字表示不同的子图。 - kwargs参数参加axes的属性
Figure分配子图的位置
gridSpec类
子图往往可以设置为显示为个性化的排列效果,类似网页的元素位置布置,比如将一行/一列中多个相邻位置的子图合并,形成不是平均分割的子图划分,这样的需要不是简单通过fig.subplot()
的参数实现的。subplot()
中个性化的子图位置划分是通过gridSpec类来设置的。
实例代码
import matplotlib.gridspec as gridspec G = gridspec.GridSpec(3, 3) axes_1 = plt.subplot(G[0, :]) axes_1.text(0.5,0.5, 'Axes 1',ha='center',va='center',size=24,alpha=.5) axes_2 = plt.subplot(G[1,:-1]) axes_2.text(0.5,0.5, 'Axes 2',ha='center',va='center',size=24,alpha=.5) axes_3 = plt.subplot(G[1:, -1]) axes_3.text(0.5,0.5, 'Axes 3',ha='center',va='center',size=24,alpha=.5) axes_4 = plt.subplot(G[-1,0]) axes_4.text(0.5,0.5, 'Axes 4',ha='center',va='center',size=24,alpha=.5) axes_5 = plt.subplot(G[-1,-2]) axes_5.text(0.5,0.5, 'Axes 5',ha='center',va='center',size=24,alpha=.5)
- 说明
matplot.gridspec.GridSpec
的定义为class matplotlib.gridspec.GridSpec(nrows, ncols, left=None, bottom=None, right=None, top=None, wspace=None, hspace=None, width_ratios=None, height_ratios=None)
- 其中,这个类的作用是相当于一个定位桩;
- left, bottom, right, top参数是0-1之间的小数,表示在figure中的相对位置,这个相对位置就是GridSpec在fig中的位置(子图再以这个GridSpec为参照来定位)--一个figure中有同时使用多个GridSped的么?或者是通过SubplotGridSpec来弄吧~
- left, bottom, right, top四个参数并不组成一个rect类的实例
- wspace和hspace使用的小数/整数都可以
- width_ratios表示每列的宽度比例,达到的效果是某些列稍微宽一些,另几列较窄;
1. width_ratios是一个数组,元素个数与ncols相同;最好的表示方法是各元素和为1;
2. width_ratios中的表示的列宽,并不包含wspace的占用空间
- 在
subplot()
中使用GridSpec
的位置序号是从0起始的,参数的用法同数组索引的用法。
Axes
参考Axes API,Axes容器不仅设定背景(patch, Rectangle类)和坐标Circle类,还包括了大多数的绘图元素类:Axis, Tick, Line2D, Text, Polygon等等。以上这些绘图元素都是Artist的子类,Axes容器提供了相应的get和set函数。
Axes 有齐全的绘图函数,可以绘制折线图、直方图、光谱图、统计图等等。入门使用方法链接:
attribute name | type | 介绍 |
---|---|---|
artists | list of Artist | 一个子图中的绘图元素的列表 |
patch | Rectangle | 作为背景的 Rectangle 对象 |
collections | list of Collection instances | |
images | list of AxesImage | AxesImage 对象列表,用来显示图片 |
legends | list of Legend | Legend 对象列表 |
lines | list of Line2D | Line2D对象列表 |
patches | list of patches | |
texts | list of Text | Text对象列表,用来显示文字 |
xaxis | matplotlib.xaxis.XAxis | 子图的横坐标属性类 |
yaxis | matplotlib.yaxis.YAxis | 子图的纵坐标属性类 |
- Axes的基本绘图函数
基本绘图方法
Helper method Artist Container ax.annotate - text annotations Annotate ax.texts ax.bar - bar charts Rectangle ax.patches ax.errorbar - error bar plots Line2D and Rectangle ax.lines and ax.patches ax.fill - shared area Polygon ax.patches ax.hist - histograms Rectangle ax.patches ax.imshow - image data AxesImage ax.images ax.legend - axes legends Legend ax.legends ax.plot - xy plots Line2D ax.lines ax.scatter - scatter charts PolygonCollection ax.collections ax.text - text Text ax.texts
1. set_xlim(left = xxx, right = xxx) 2. set_ylim(top = xxx, bottom = xxx)
Axis
Axis容器包括坐标轴上的刻度线(tickline)、刻度文本(ticklabel)、坐标网格(grid)以及坐标轴标题(label)等内容。
- 刻度包括主刻度和副刻度
- 主刻度是区间较大的刻度,绘图中一般显示得明显;副刻度是区间较小的刻度,绘图中显示得紧密,不明显,分别通过axis.get_major_ticks()和Axis.get_minor_ticks()方法获得。
- 实际上每个刻度线都是一个XTick或者YTick对象,包括实际的刻度线和刻度文本。为了分别设置刻度线和文本更方便,Axis对象提供了get_ticklabels和get_ticklines方法
for label in axis.get_ticklabels(): label.set_color("red") label.set_rotation(45) label.set_fontsize(6) for line in axis.get_ticklines(): line.set_color("green") line.set_markersize(25) line.set_markeredgewidth(3)
- 调整横坐标显示在图表上方或者图表下方
- 横坐标的刻度线和刻度文本显示在图表上方或者图表下方
XAxis.tick_top()
|XAxis.tick_bottom()
不能同时上方下方都显示横坐标的刻度文本 - 设置横坐标的刻度线显示在图表的上方或者图表下方
XAxis.set_ticks_position()
- "both", "top", "bottom", "default", "none"
-
XAxis.set_ticks_position("top")
与XAxis.tick_top()
是相同效果;XAxis.set_ticks_position("bottom")
与XAxis.tick_bottom()
是相同效果。
- XAxis.set_ticks_position("both")是上下都有刻度线
- 调整纵坐标显示在图表左侧或者右侧
YAxis.tick_left()
|YAxis.tick_right()
- 横坐标的刻度线和刻度文本显示在图表上方或者图表下方
- 调整坐标的刻度线在直方图中的对齐
在画直方图的图示时,设置tick对齐直方图的左边、右边还是中间
Axis中设置刻度线、刻度文本的最直接方法:
1. 外观设置(刻度线左右/上下 + 刻度文本左右/上下 + 刻度线长短/粗细/颜色 + 刻度文本颜色/倾角等)
```
for tick in ax1.xaxis.get_major_ticks():
tick.label1On = True
tick.label2On = True
tick.tick1On = True
tick.tick2On = True
tick.tick1line.set_color('red')
tick.tick1line.set_markersize(35)
tick.tick1line.set_markeredgewidth(5)
tick.label1.set_color('blue')
tick.tick2line.set_color('blue')
tick.tick2line.set_markersize(25)
tick.tick2line.set_markeredgewidth(10)
```
1. 上面的方法,可以很细致地设置一些图示的细节,达到了个性化设置的目的;
2. 对于需要简洁代码的场景,可以使用的`XAxis.tick_top()`这样的代码直接设置刻度线和刻度文本的位置,可以说各有利弊。
2. 刻度文本设置
直接使用列表赋值
Patch
Legend图示
入门参考
legend图示是分一个个条目(entry-->key:label)的
legend中一个个条目分别对应底层的一个个handle(这些handle只对限定的曲线才会默认生成)
- legend()函数的参数
pyplot.legend(),axe.legend()
a. legend(曲线实例名)
b. legend(曲线实例名,label名)
line_up, = plt.plot([1,2,3], label='Line 2') line_down, = plt.plot([3,2,1], label='Line 1') plt.legend(handles=[line_up, line_down])
或
line_up, = plt.plot([1,2,3], label='Line 2') line_down, = plt.plot([3,2,1], label='Line 1') plt.legend([line_up, line_down], ['Line Up', 'Line Down'])
参数列表
parameter key name parameter value 注解 handles [ artiest name
]曲线名;第一个参数,不加关键字handles也可以,一定是 []
包围的loc 'best', 'upper(lower/center) left(right)', 'right', 'lower(upper) center', 'center' --- bbox_to_anchor (float, float) legend location in bbox_transform coordinates,可以调整图示legend显示到Axe外面 ncol integer 图示的分栏数,默认是1,即1栏; 可以分成2栏/3栏,显示效果好 mode "expand" or None 使得这个图示框会调整宽度 fontsize 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large' 或者integer numpoints / scatterpoints integer markerfirst True/False 是否曲线标识在前 labelspacing float or None 条目之间的垂直间距 columnspacing float or None 分栏之间的平行间距 shadow True/False 是否有背景(背景颜色legend.get_frame().set_facecolor('') facecolor 'inherit'或者'blue','pink' 背景颜色 edgecolor 'inherit'或者'blue','pink' 背景边界颜色 - bbox_to_anchor参数可以把图示框显示在figure外面,配合loc参数的值,可以调整图示偏左/偏右显示。
- bbox_to_anchor的参数 (1.05, 1)或者(0.,1.02, 1., 1.02)这样
- shadow参数的作用还不清楚
- tips
一个figure添加多个图示legend,及多条曲线对应各自的legend等,
代码是这么写:
import matplotlib.pyplot as plt line1, = plt.plot([1,2,3], label="Line 1", linestyle='--') line2, = plt.plot([3,2,1], label="Line 2", linewidth=4) # Create a legend for the first line. first_legend = plt.legend(handles=[line1], loc=1) # Add the legend manually to the current Axes. ax = plt.gca().add_artist(first_legend) # Create another legend for the second line. plt.legend(handles=[line2], loc=4) plt.show()
这里面,多个legend要使用
ax = plt.gca().add_artist(first_legend)
这样的语句handlers
Axes.annotate类
使用方法只调用一个函数Axes.annotate(*args, **kwargs)
,如:
ax1.annotate('what a setup',xy=(0.2,0.2),xytext=(0.2,0.8),fontsize=12,
arrowprops=dict(arrowstyle="<|-"))
其中args参数如下:
parameter key name | parameter value | 注解 |
---|---|---|
s | 注释文字 | 注释文字 |
xy | 被注释点的坐标 | xy=(0.8,0,8) |
xytext | 注释文字所在坐标 | xytext=(0.2, 0.8) |
xycoords | 以上两个坐标采用的坐标系 | default to 'data',被注释点使用的坐标系 |
arrowprops | dict(arrowstyle="fancy", connectionstyle="") | 文字和注释点之间标线的样式,FancyArrowPatch |
PS:有一个博主十几篇关于应用matplotlib绘图的博客Chris Chen,我看了以后非常有启发,已关注他的博客更新。