Matplotlib——中级

 关于Matplotlib的愚见

初级中,我只是简单介绍了Matplotlib的使用方法,在中级部分,我系统地说一下我总结的内容。canvas

 

上图是我画的关于Matplotlib几个对象之间的关系图。它们都来自于一个叫作Artist的基类。咱们知道绘制图的基础是Canvas,它是咱们真正进行绘图的后端。Artist只是在程序逻辑上的绘图,它必须链接后端绘图程序才能真正在屏幕上绘制出来(或者保存为文件)。咱们能够将canvas理解为绘图的物理(或者说硬件)实现。对于每一个Artist类的对象,都有findobj()方法,来显示该对象所包含的全部下层对象。后端

 Artist对象的全部属性都经过相应的get_*和set_*函数来读写。在后面的例子中,不少都不是对fig的操做,而是对ax的操做,这里要记住这种方法。ide

fig.set_alpha(0.5*fig.get_alpha())

 若是要同时给多个属性进行设置的话,可使用set函数: 函数

fig.set(alpha = 0.5, zorder=2)

 使用matplotlib.pyplot.getp 函数则能够方便地输出Artist对象的全部属性名和值。字体

plt.getp(fig.patch)

生成多张画布

好比spa

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 10) print(x) y = x*2+1 z = x**2 plt.figure() plt.plot(x, y) plt.figure() plt.plot(x, z) plt.show()

 运行效果为:3d

 和   code

若是不写的话,默认是从1开始算。咱们也能够在里面指定参数,用来给这个画布编号,好比:对象

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 100) y = x*2+1 z = x**2 plt.figure() plt.plot(x, y) plt.figure(num=3, figsize=(8, 5)) plt.plot(x, z) plt.show()

 运行效果为:blog

  和   

坐标轴经常使用设置

  • xlim、ylim方法设置坐标轴刻度取值范围
  • xlabel、ylabel方法设置x轴和y轴的标题
  • xticks,yticks方法设置x,y轴的刻度标签值

例子:

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 100) y = x*2+1 plt.figure(1) plt.plot(x, y) plt.figure(2) plt.plot(x, y) # 设置坐标轴取值范围
plt.xlim((-2, 2)) plt.ylim((0, 3)) # 设置坐标轴标题
plt.xlabel("我是横坐标") plt.ylabel("我是纵坐标") # 设置刻度标签
new_ticks = np.linspace(-1, 4, 6) plt.xticks(new_ticks) # 将原有x轴刻度标注修改,图也会随着坐标改变而改变。
plt.yticks([1, 2, 3], ["", r"$I\ am\ middle$", ""])     # 用第二个参数的值一一替换第一个参数的值。
 plt.show()

 运行效果为:

  和   

坐标轴边框设置及位置移动

这里咱们须要认识的是:gca,它的意思是get current axis(获取当前轴)。

获取了当前绘图区(轴)以后咱们再经过ax.spines对其进行操做,spines是脊柱的意思。

具体的操做以下例:

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 100) y = x*2+1 plt.figure(1) plt.plot(x, y) plt.figure(2) plt.plot(x, y) # 去掉上和右边的边框线
ax = plt.gca()           # 获取当前绘图区
ax.spines["right"].set_color("none") ax.spines["top"].set_color("none") # 更改坐标轴位置
ax.xaxis.set_ticks_position("bottom")     # 由于绘制的图形中,上下都算是坐标轴,咱们若是要绘制坐标系的话须要指定其中一个为坐标轴,这里咱们是将下坐标轴来做为X轴。
ax.yaxis.set_ticks_position("left")     # 同上,用左轴做为Y轴。
ax.spines["bottom"].set_position(("data", 0))  # data表示用值来选择,这个句话的意思就是用X坐标轴上值为0的点做为坐标系原点。"data"只是一个参数,还有outward,axes等参数,它们都有不一样的意义。
ax.spines["left"].set_position(("data", 0))   # 同上
 plt.show()

  运行结果为:

  和     

图例的设置

在初级,咱们说过简单的设置图例,这里咱们在进行一些拓展的说明。

例子:

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 100) y = x*2+1 z = x**2 plt.figure(1) L1, = plt.plot(x, y, label="$x*2+1$")  # L1后面的逗号是matplotlib特殊的写法
L2, = plt.plot(x, z, label="$x^2$") plt.legend(handles=[L1], labels=["a", "b"], loc="best") # handles是用来控制放入图例的内容。labels是用来给handles对应的图修改图例名。
 plt.show()

 运行结果为:

在图片中添加注解

在讲解给图片添加注解以前呢,咱们须要认识一下scattter函数,咱们在绘制图像的时候使用的是plot,它是线的形式,若是咱们使用scatter的话,它就会用点的形式来绘制。 

 下面是示例代码:

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 100) y = x*2+1 plt.figure(1) plt.plot(x, y) plt.figure(2) plt.plot(x, y) # 去掉上和右边的边框线
ax = plt.gca()           # 获取当前绘图区
ax.spines["right"].set_color("none") ax.spines["top"].set_color("none") # 更改坐标轴位置
ax.xaxis.set_ticks_position("bottom")     # 由于绘制的图形中,上下都算是坐标轴,咱们若是要绘制坐标系的话须要指定其中一个为坐标轴,这里咱们是将下坐标轴来做为X轴。
ax.yaxis.set_ticks_position("left")     # 同上,用左轴做为Y轴。
ax.spines["bottom"].set_position(("data", 0))  # data表示用值来选择,这个句话的意思就是用X坐标轴上值为0的点做为坐标系原点。"data"只是一个参数,还有outward,axes等参数,它们都有不一样的意义。
ax.spines["left"].set_position(("data", 0))   # 同上

# 设置标注
x0 = 1 y0 = 2*x0 + 1 plt.scatter(x0, y0, s=50, color="b")      # 设置要标注的点,scatter和plot函数同样能够绘制图形,不过它是用点构成的图形。其中s是控制大小,color是控制颜色。
plt.plot([x0, x0], [y0, 0], "k--", lw=1)    # 设置一个黑色的虚线。
 plt.annotate(r'$2x+1=%s$' % y0, xy=(x0, y0), xycoords='data', xytext=(+30, -30), textcoords='offset points', fontsize=16, arrowprops=dict(arrowstyle='->', connectionstyle="arc3,rad=.2")) """ 下面是annotate中每一个参数设置的意思: plt.annotate(r"$2x+1\ =\ %s$" % y0, # 标注的文字描述 xy=(x0, y0), # xy是设置要标注的点。 xycoords="data", # xycoords表示前面xy设置的内容以"data"的值为基准。 xytext=(+30, -30), # 标注信息在要标注的点的横坐标加30,纵坐标减30的位置显示。 textcoords="offset point", # xtext设置的内容以"offset point",也就是偏移量为基准。 fontsize=16, # 设置字体的大小 arrowprops=dict(arrowstyle="->", connectionstyle="arc3, rad=.2") # 设置箭头。arrowstyle的设置表示使用箭头,connectionstyle是用来设置弧度的。 ) """ plt.text(-3.7, 3, r'$This\ is\ the\ some\ text. \mu\ \sigma_i\ \alpha_t$', fontdict={'size': 16, 'color': 'r'}) """ 下面是text中每一个参数设置的意思: plt.text(-3.7, 3, # 文字显示的位置 r'$This\ is\ the\ some\ text. \mu\ \sigma_i\ \alpha_t$', # 显示的文字 fontdict={'size': 16, 'color': 'r'}) # 文字的格式 """ plt.show()

 运行结果以下:

  和   

当线遮挡刻度标注解决办法

示例代码:

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 50) y = 0.1*x plt.figure() # 在 plt 2.0.2 或更高的版本中, 设置 zorder 给 plot 在 z 轴方向排序
plt.plot(x, y, linewidth=10, zorder=1) plt.ylim(-2, 2) ax = plt.gca() ax.spines['right'].set_color('none') ax.spines['top'].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)) for label in ax.get_xticklabels() + ax.get_yticklabels(): label.set_fontsize(12)    # 设置字体大小
 label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.7, zorder=2)) """ set_bbox的参数说明: label.set_bbox(dict(facecolor='white', # 背景颜色 edgecolor='None', # 边框 alpha=0.7, # 背景透明度 zorder=2)) # 在 plt 2.0.2 或更高的版本中, 设置 zorder 给 plot 在 z 轴方向排序 """ plt.show()

 运行结果:

 同画布绘制多图

方式1:使用subplot来绘制

在初级中,咱们说过咱们画一个图是要在一个画布上,咱们画的图在Matplotlib中被称为轴或者绘图区,一个画布中能够包含多个绘图区,每一个绘图区都拥有本身坐标系统的绘图区域。咱们能够经过subplot()函数来快速绘制有多个绘图区的画布。

它的格式为:

plt.subplot(numRows, numCols, plotNum)

 subplot将整个绘图区域划分为numRows行和numCols列个区域,而后按照从左到右,从上到下的顺序对每一个子区域进行编号,以下图所示。

在使用的时候,有的人可能会看到subplot(324)这样的设置,这样也是正确的写法,它等效于subplot(3, 2, 3)。若是numRows、numCols、plotNum这三个数都小于10的话,能够把它们缩写为一个整数。

若是新建的轴和以前的轴位置重叠的话,原来的轴会被覆盖。

使用例子以下:

import matplotlib.pyplot as plt plt.figure() plt.subplot(2, 2, 1) plt.plot([0, 1], [0, 1]) plt.subplot(2, 2, 2) plt.plot([0, 1], [0, 2]) plt.subplot(223) plt.plot([0, 1], [0, 3]) plt.subplot(224) plt.plot([0, 1], [0, 4]) plt.show()

 运行效果为:

咱们还能够自定义它们的跨列显示

import matplotlib.pyplot as plt plt.figure() plt.subplot(2, 1, 1) plt.plot([0, 1], [0, 1]) plt.subplot(2, 3, 4) plt.plot([0, 1], [0, 2]) plt.subplot(235) plt.plot([0, 1], [0, 3]) plt.subplot(236) plt.plot([0, 1], [0, 4]) plt.show()

 运行代码以下:

 

说明:

使用subplot是比较别扭的,要大概了解它的绘制顺序。在上面例子中,

(2, 1, 1),第一个参数表示figure分为两行,第二个参数表示分为一列,第三个表示它使用第一个图绘制。

(2, 3, 4),第一个参数表示figure分为两行,第二个参数表示分为三列,第三个表示它使用第四个图绘制(由于第一行是跨3列,因此这个是从第四个开始计算)。(2, 3, 5)和(2, 3, 6)同理。

 不一样figure切换加figure切分的例子:

import numpy as np
import matplotlib.pyplot as plt 

plt.figure(1)
plt.figure(2)
ax1= plt.subplot(221)
ax2 = plt.subplot(222)
ax3 = plt.subplot(212)
x = np.linspace(0, 3, 100)
for i in range(5):
    plt.figure(1)
    plt.plot(x, np.exp(i*x/3))
    plt.sca(ax1)
    plt.plot(x, np.sin(i*x))
    plt.sca(ax2)
    plt.plot(x, np.cos(i*x))
    plt.sca(ax3)
    plt.plot(x, np.exp(i*x/3))
plt.show()

 它的效果如图:

 从上面的例子中咱们能够看出:使用subplot()会返回它所建立的绘图区,经过变量保存后,咱们可使用sca()函数交替让它们成为当前绘图区,而后调用plot()函数在这个绘图区里面绘制图形。若是有多个画布,咱们能够用figure()函数来指定一个画布。若是这个画布存在则将该画布变为当前画布,若是不存在则建立一个对应的画布。

方式2:使用subplot2grid来绘制

subplot2grid使用起来要比第一种subplot的方式要更直观和清晰些。咱们来看看例子:

import matplotlib.pyplot as plt plt.figure() ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3, rowspan=1)   # 第一个参数是整个figure分为几个块,第一个为行,第二个为列;第二个参数为这个图形的起始位置,位置是从0开始计算的;第三个和第四个分别设置这个图形占据几列和几行。 ax1.plot([1, 2], [2, 2]) ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2) ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2) ax4 = plt.subplot2grid((3, 3), (2, 0)) ax5 = plt.subplot2grid((3, 3), (2, 1))

 运行结果:

方式3:使用gridspec来绘制

使用它以前咱们要先导入:

import matplotlib.gridspec as gridspec

 让咱们再看看实际的使用:

import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec plt.figure() gs = gridspec.GridSpec(3, 3) # 将一个figure分红3*3的格子。
 ax1= plt.subplot(gs[0, :])     # 占第0行和全部列
ax2 = plt.subplot(gs[1, :2])    # 占第1行和第2列前的全部列
ax3 = plt.subplot(gs[1:, 2])   # 占第1行后的全部行和第2列
ax4 = plt.subplot(gs[-1, 0])    # 占倒数第1行和第0列
ax5 = plt.subplot(gs[-1, -2])  # 占倒数第1行和倒数第2列.

 运行结果:

方式4:使用subplots来绘制

注意,这个和第一种方法不一样,第一种建立方式咱们使用的是subplot,这里咱们使用的是subplots。

 使用例子:

import matplotlib.pyplot as plt f,((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, sharex=True, sharey=False) plt.tight_layout() # 不加会紧凑显示
ax1.plot([1, 2], [2, 2])   # ax1中绘制图像。
plt.show() """ 说明: 使用plt.subplots创建一个2行2列的图像窗口, sharex=True表示共享x轴坐标, sharey=True表示共享y轴坐标。 ((ax11, ax12), (ax13, ax14))表示第1行从左至右依次放ax1和ax2, 第2行从左至右依次放ax3和ax4. """

 运行效果:

 绘制图内图

代码:

# 导入pyplot模块
import matplotlib.pyplot as plt # 初始化figure
fig = plt.figure() # 建立数据
x = [1, 2, 3, 4, 5, 6, 7] y = [1, 3, 4, 2, 5, 8, 6] left, bottom, width, height = 0.1, 0.1, 0.8, 0.8    # 4个值都是占整个figure坐标系的百分比。在这里,假设figure的大小是10x10,那么大图左边距为1,底边距为1,宽8,高8的坐标系内。

# 绘制外围图
ax1 = fig.add_axes([left, bottom, width, height]) ax1.plot(x, y, 'r') ax1.set_xlabel('x') ax1.set_ylabel('y') ax1.set_title('title') # 绘制内图
left, bottom, width, height = 0.2, 0.5, 0.3, 0.3 ax2 = fig.add_axes([left, bottom, width, height])   # 假设figure的大小是10x10,那么大图左边距为2,底边距为5,宽3,高3的坐标系内。
ax2.plot(y, x, 'b') ax2.set_xlabel('x') ax2.set_ylabel('y') ax2.set_title('title inside 1')

 运行结果为:

相关文章
相关标签/搜索