Matplotlib 是 Python 中最强大的数据可视化库之一,但其默认样式较为基础。 通过定制化设计,可以创建专业、精美的图表。
本节作为 matplotlib
的入门介绍,将较为深入地挖掘几个例子,
从中理解和学习 matplotlib
绘图的一些基本概念。
matplotlib
的 pyplot
子库提供了和 matlab
类似的绘图API,方便用户快速绘制2D图表。
让我们先来看一个简单的例子:
调用 pyplot
库快速将数据绘制成曲线图,
matplotlib
中的快速绘图的函数库可以通过如下语句载入:
%matplotlib inline
import matplotlib.pyplot as plt
生成示例数据:
import numpy as np
x = np.linspace(0, 10, 1000)
y = np.sin(x)
z = np.cos(x**2)
开始绘图:
接下来调用 figure
创建一个绘图对象,并且使它成为当前的绘图对象。
plt.figure(figsize=(8,4))
<Figure size 800x400 with 0 Axes>
<Figure size 800x400 with 0 Axes>
plt.plot(x,y,label="$sin(x)$",color="red",linewidth=2)
plt.plot(x,z,"b--",label="$cos(x^2)$")
plt.xlabel("Time(s)")
plt.ylabel("Volt")
plt.title("PyPlot First Example")
plt.ylim(-1.2,1.2)
plt.legend()
plt.show()
Matplotlib
会自动创建一个绘图对象。如果需要同时绘制多幅图表的话,
可以是给 figure
传递一个整数参数指定图标的序号,如果所指定序号的绘图对象已经存在的话,
将不创建新的对象,而只是让它成为当前绘图对象。
通过 figsize
参数可以指定绘图对象的宽度和高度,单位为英寸;
dpi
参数指定绘图对象的分辨率,即每英寸多少个像素,缺省值为80。
因此本例中所创建的图表窗口的宽度为 8*80 = 640
像素。
但是用工具栏中的保存按钮保存下来的 png
图像的大小是 800*400
像素。
这是因为保存图表用的函数 savefig
使用不同的DPI配置,savefig
函数也有一个 dpi
参数,
如果不设置的话,将使用 matplotlib
配置文件中的配置,此配置可以通过如下语句进行查看,
关于配置文件将在后面的章节进行介绍:
import matplotlib
matplotlib.rcParams["savefig.dpi"]
'figure'
下面的两行程序通过调用 plot
函数在当前的绘图对象中进行绘图:
plt.plot(x,y,label="$sin(x)$",color="red",linewidth=2)
plt.plot(x,z,"b--",label="$cos(x^2)$")
plt.show()
plot
函数的调用方式很灵活,第一句将x,y数组传递给 plot
之后,用关键字参数指定各种属性:
label
: 给所绘制的曲线一个名字,此名字在图示(legend)中显示。 只要在字符串前后添加$
符号,matplotlib
就会使用其内嵌的latex
引擎绘制的数学公式。color
: 指定曲线的颜色linewidth
: 指定曲线的宽度
第二句直接通过第三个参数 b--
指定曲线的颜色和线型,这个参数称为格式化参数,它能够通过一些易记的符号快速指定曲线的样式。
其中 b
表示蓝色,--
表示线型为虚线。在IPython中输入 plt.plot ?
可以查看格式化字符串的详细配置。
接下来通过一系列函数设置绘图对象的各个属性。在此之前要注意, 在交互环境下, 绘图函数除了绘图,还有清空内存画板的作用。 所以为了使用前面的数据,需要重新进行绘制,如下:
plt.plot(x,y,label="$sin(x)$",color="red",linewidth=2)
plt.plot(x,z,"b--",label="$cos(x^2)$")
plt.xlabel("Time(s)")
plt.ylabel("Volt")
plt.title("PyPlot First Example")
plt.ylim(-1.2,1.2)
plt.legend()
<matplotlib.legend.Legend at 0x7f1b1e1816a0>
xlabel
: 设置X轴的文字ylabel
: 设置Y轴的文字title
: 设置图表的标题ylim
: 设置Y轴的范围legend
: 显示图示
最后调用 plt.show()
显示出我们创建的所有绘图对象。
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 5, 0.1)
plot
返回一个列表,通过 line
,获取其第一个元素
line, = plt.plot(x, x*x)
# 调用Line2D对象的set_*方法设置属性值
line.set_antialiased(False)
# 同时绘制sin和cos两条曲线,lines是一个有两个Line2D对象的列表
lines = plt.plot(x, np.sin(x), x, np.cos(x)) #
# 调用setp函数同时配置多个Line2D对象的多个属性值
plt.setp(lines, color="r", linewidth=2.0)
plt.setp(line,linewidth=1.0)
plt.show()
这段例子中,通过调用 Line2D
对象 line
的 set_antialiased
方法,
关闭对象的反锯齿效果。或者通过调用 plt.setp
函数配置多个 Line2D
对象的颜色和线宽属性。
同样可以通过调用 Line2D
对象的 get_*
方法,或者 plt.getp
函数获取对象的属性值:
line.get_linewidth()
1.0
返回 color
属性
plt.getp(lines[0], "color")
'r'
输出全部属性
plt.getp(lines)
agg_filter = None alpha = None animated = False antialiased or aa = True bbox = Bbox(x0=0.0, y0=-0.9999232575641008, x1=4.9, y1=0.... children = [] clip_box = TransformedBbox( Bbox(x0=0.0, y0=0.0, x1=1.0, ... clip_on = True clip_path = None color or c = r dash_capstyle = butt dash_joinstyle = round data = (array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.... drawstyle or ds = default figure = Figure(640x480) fillstyle = full gapcolor = None gid = None in_layout = True label = _child1 linestyle or ls = - linewidth or lw = 2.0 marker = None markeredgecolor or mec = r markeredgewidth or mew = 1.0 markerfacecolor or mfc = r markerfacecoloralt or mfcalt = none markersize or ms = 6.0 markevery = None mouseover = False path = Path(array([[ 0. , 0. ], [ 0... path_effects = [] picker = None pickradius = 5 rasterized = False sketch_params = None snap = None solid_capstyle = projecting solid_joinstyle = round tightbbox = Bbox(x0=102.54545454545455, y0=69.6, x1=553.454545... transform = CompositeGenericTransform( TransformWrapper( ... transformed_clip_path_and_affine = (None, None) url = None visible = True window_extent = Bbox(x0=102.54545454545455, y0=69.6, x1=553.454545... xdata = [0. 0.1 0.2 0.3 0.4 0.5]... xydata = [[0. 0. ] [0.1 0.09983342] ... ydata = [0. 0.09983342 0.19866933 0.29552021 0.389... zorder = 2
注意 getp
函数只能对一个对象进行操作,它有两种用法:
- 指定属性名:返回对象的指定属性的值
- 不指定属性名:打印出对象的所有属性和其值
matplotlib
的整个图表为一个 Figure
对象,此对象在调用 plt.figure
函数时返回,
也可以通过 plt.gcf
函数获取当前的绘图对象:
f = plt.gcf()
plt.getp(f)
agg_filter = None alpha = None animated = False axes = [] children = [<matplotlib.patches.Rectangle object at 0x7fdfc53... clip_box = None clip_on = True clip_path = None constrained_layout = False constrained_layout_pads = (None, None, None, None) default_bbox_extra_artists = [] dpi = 100.0 edgecolor = (1.0, 1.0, 1.0, 1.0) facecolor = (1.0, 1.0, 1.0, 1.0) figheight = 4.8 figure = Figure(640x480) figwidth = 6.4 frameon = True gid = None in_layout = True label = layout_engine = None linewidth = 0.0 mouseover = False path_effects = [] picker = None rasterized = False size_inches = [6.4 4.8] sketch_params = None snap = None suptitle = supxlabel = supylabel = tight_layout = False tightbbox = Bbox(x0=0.0, y0=0.0, x1=6.4, y1=4.8) transform = IdentityTransform() transformed_clip_path_and_affine = (None, None) url = None visible = True window_extent = TransformedBbox( Bbox(x0=0.0, y0=0.0, x1=6.4, ... zorder = 0
<Figure size 640x480 with 0 Axes>
Figure
对象有一个 axes
属性,其值为 AxesSubplot
对象的列表,
每个 AxesSubplot
对象代表图表中的一个子图,前面所绘制的图表只包含一个子图,
当前子图也可以通过 plt.gca
获得:
plt.getp(f, "axes")
[]
plt.gca()
<Axes: >
用 plt.getp
可以发现 AxesSubplot
对象有很多属性,
例如它的 lines
属性为此子图所包括的 Line2D
对象列表:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 5, 0.1)
plot
函数返回一个 matplotlib.lines.Line2D
对象的列表,
plot
返回一个列表,通过 line
,获取其第一个元素
line, = plt.plot(x, x*x)
line.set_antialiased(False) # 调用Line2D对象的set_*方法设置属性值
# 同时绘制sin和cos两条曲线,lines是一个有两个Line2D对象的列表
lines = plt.plot(x, np.sin(x), x, np.cos(x))
# 调用setp函数同时配置多个Line2D对象的多个属性值
alllines = plt.getp(plt.gca(), "lines")
alllines
<a list of 3 Line2D objects>
alllines[0] == line
True
其中的第一条曲线就是最开始绘制的那条曲线。
通过这种方法可以很容易地查看对象的属性和它们之间的包含关系,找到需要配置的属性。
matplotlib
还提供了名为 pylab
的模块,其中包括了许多 numpy
和 pyplot
中常用的函数,
方便用户快速进行计算和绘图,可以用于IPython中的快速交互式使用。
(pylab combines pyplot with numpy into a single namespace. This is convenient for interactive work, but for programming it is recommended that the namespaces be kept separate)
意思就是说 pylab
结合了 pyplot
和 numpy
,对交互式使用来说比较方便,
既可以画图又可以进行简单的计算。但是,对于一个项目来说,建议分别导入使用。