Matplotlib——中级  关于Matplotlib的愚见 生成多张画布 坐标轴常用设置 坐标轴边框设置及位置移动 图例的设置 在图片中添加注解 当线遮挡刻度标注解决办法  同画布绘制多图  绘制图内图

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

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

 

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

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

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

 Artist对象的所有属性都通过相应的get_*和set_*函数来读写。在后面的例子中,很多都不是对fig的操作,而是对ax的操作,这里要记住这种方法。

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

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

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

 使用matplotlib.pyplot.getp 函数则可以方便地输出Artist对象的所有属性名和值。

plt.getp(fig.patch)

生成多张画布

比如

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()

 运行效果为:

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图 和   Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

如果不写的话,默认是从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()

 运行效果为:

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图  和   Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

坐标轴常用设置

  • 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()

 运行效果为:

 Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图 和   Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

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

这里我们需要认识的是: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()

  运行结果为:

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图  和     Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

图例的设置

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

例子:

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()

 运行结果为:

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

在图片中添加注解

在讲解给图片添加注解之前呢,我们需要认识一下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()

 运行结果如下:

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图  和   Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

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

示例代码:

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()

 运行结果:

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

 同画布绘制多图

方式1:使用subplot来绘制

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

它的格式为:

plt.subplot(numRows, numCols, plotNum)

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

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

在使用的时候,有的人可能会看到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()

 运行效果为:

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

我们还可以自定义它们的跨列显示

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()

 运行代码如下:

 Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

说明:

使用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()

 它的效果如图:

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

 从上面的例子中我们可以看出:使用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))

 运行结果:

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

方式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列.

 运行结果:

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

方式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.
"""

 运行效果:

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图

 绘制图内图

代码:

# 导入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')

 运行结果为:

Matplotlib——中级
 关于Matplotlib的愚见
生成多张画布
坐标轴常用设置
坐标轴边框设置及位置移动
图例的设置
在图片中添加注解
当线遮挡刻度标注解决办法
 同画布绘制多图
 绘制图内图