绘制网格线、水平参考线及垂直参考区域

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0.05, 10, 1000)  # 函数在0.05到10之间均匀地取1000个数
y = np.cos(x)

# 用于呈现变化趋势
plt.plot(x, y, ls='-.', lw=2, label='plot figure')  # x是x轴上的值,y是y轴上的值。ls折线线条风格,lw折线线条宽度,label标记图像的标签文本
plt.xlabel('x-axis')  # 设置x轴标签文本
plt.ylabel('y-axis')  # 设置y轴标签文本
plt.legend()
plt.grid(linestyle=":", color="r")  # 绘制刻度线的网格线
plt.show()

plt.axhline(y=0.0, c='r', ls='--', lw=2)  # 垂直于y轴的参考线
plt.axvline(x=4.0, c='r', ls='--', lw=2)  # 垂直于x轴的参考线

plt.axhspan(ymin=0.0, ymax=0.5, facecolor='y', alpha=0.3)   # ymin参考区域起点,ymax参考区域终点, facecolor参考区域填充色,alpha参考区域颜色透明度
plt.axvspan(xmin=4.0, xmax=6.0, facecolor='y', alpha=0.3)  # xmin参考区域起点,xmax参考区域终点, facecolor参考区域填充色,alpha参考区域颜色透明度

图形每个曲线的标签

import matplotlib.pyplot as plt
import numpy as np
plt.title("y=cos(x)")  # 添加图片标题
x = np.arange(0, 10, 1)
plt.plot(x, x, 'r-.', x, np.cos(x), 'g--', marker='*')
plt.legend(["red", "green"], loc='lower right')  # loc='upper left'
plt.show()

添加图形中带指向性和不带指向性的注释文本

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0.05, 10, 1000)  # 函数在0.05到10之间均匀地取1000个数
y = np.cos(x)

# 用于呈现变化趋势
plt.plot(x, y, ls='-.', lw=2)  # x是x轴上的值,y是y轴上的值。ls折线线条风格,lw折线线条宽度
plt.legend()
plt.annotate("maximum",  # 注释的标签内容
             xy=(np.pi*2, 1.0),  # 要被注释的地方位置坐标
             xytext=((np.pi*2)+1.0, .8),  # 注释文本的位置
             weight="bold",  # 注释文本字体粗细
             color='g',
             arrowprops= dict(arrowstyle='->', connectionstyle='arc3, rad=0.2', color='g')  # 指向注释点的箭头属性
)
plt.show()

更多更详细的用法

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0.05, 10, 1000)  # 函数在0.05到10之间均匀地取1000个数
y = np.cos(x)
plt.plot(x, y, ls='-.', lw=2)  
plt.legend()
plt.text(3.10, 0.09, 'y=cos(x)', weight='bold', color='y')
plt.show()

划分画布(划分子区域)

1.等分画布subplot()

子区函数subplot()的三个参数分别是整数C、整数R和整数P,表示在C行、R列的网格布局上,子区subplot()会被放置在第P个位置上,即为将被创建的子区编号,子区编号从1开始,起始于右上角,序号依次向右递增。也就是说,每行的子区位置都是从左向右进行升序计数的,subplot(2,3,4)是第2行的第1个子区也可以写作subplot(234)
参考这篇文章第3节的作图

2.非等分区域上展示图形(实例方法add_subplot())

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()

x = np.linspace(0.0, 2*np.pi)
y = np.cos(x)*np.sin(x)

ax1 = fig.add_subplot(121)
ax1.margins(0.03)
ax1.plot(x, y, ls='-', lw=1, c='b')

ax2 = fig.add_subplot(222)
ax2.margins(0.7, 0.7)
ax2.plot(x, y, ls='-', lw=2, c='r')

ax3 = fig.add_subplot(224)
ax3.margins(x=0.1, y=0.3)
ax3.plot(x, y, ls='-', lw=3, c='g')

plt.show()

其中margins(m)设置数据范围的空白区域,m倍的数据区间会被添加到x轴y轴两端。m取值范围是大于-0.5的任意浮点数。负数的情况就是只能看见部分图像,像放大了的感觉。

3.定制网格区域subplot2grid()(也是非等分区域上展示图形)

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False

plt.subplot2grid((2, 3), (0, 0), colspan=2)
x = np.linspace(-1.0, 5.0, 100)
y = np.random.randn(100)
plt.scatter(x, y, c='c')
plt.title('散点图')

plt.subplot2grid((2, 3), (0, 2))
plt.title('空白区域')

plt.subplot2grid((2, 3), (1, 0), colspan=3)
x = np.linspace(0.0, 4.0, 100)
y1 = np.sin(x)
plt.plot(x, y1, lw=2, ls='-')
plt.xlim(0, 3)
plt.grid(True, ls=":", c='r')
plt.title("折线图")

plt.suptitle("subplot2grid()函数的实例展示")

plt.show()

函数subplot2grid(shape, loc)。shape就表示几行几列的网格布局,loc表示以第几行第几列为起点(从0算起哦),colspan表示横跨多少列,当然就有rowspan表示横跨多少行。

by the way,函数suptitle()指绘制Figure画布(就是整张图片标题)标题的文本内容,函数title()绘制Axes实例(就是每一个小图像的标题)的图形标题文本。

4.画布中多个子区域绘图(等分)subplots()

和2有点异曲同工的味道,但是更加灵活。

函数subplots()的返回值是一个( fig, ax)元组,其中,fig是Figure实例,ax可以是一个axis对象,如果是多个子区被创建,那么ax可以是一个axis对象数组。因此,使用函数subplots()可以创建一张画布带有多个子区的绘图模式的网格布局。
比如通过调用函数subplots(1,2),生成一个画布对象和一个坐标轴实例数组,画布对象和实例数组分别存储在变量fig和ax中。然后分别在坐标轴axl和坐标轴ax2上绘制图。

如果我们想要改变子区边缘相距画布边缘的距离和子区边缘之间的高度与宽度的距离,可以调
用函数subplots _adjust(*agrs,**kwargs)进行设置, 其中的关键字参数left、right、 bottom、top、 hspacewspace都有默认值,而且是使用Axes坐标轴系统度量的,即使用闭区间[0,1]的浮点数,前四个关键字参数可以调节子区距离画布的距离,关键字参数wspace控制子区之间的宽度距离,关键字参数hspace控制子区之间的高度距离。因此,借助函数subplots adjust0可以有效实现子区的画布布局的空间位置的调整。

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False

fig, ax = plt.subplots(2, 3)

# 231
colors = ['#8dd3c7', '#ffffb3', '#bebada']
ax[0, 0].bar([1, 2, 3], [0.6, 0.2, 0.8], color=colors, width=0.5, hatch='///', align='center')
ax[0, 0].errorbar([1, 2, 3], [0.6, 0.2, 0.8], yerr=0.1, capsize=0, ecolor='#377eb8', fmt="o:")
ax[0, 0].set_ylim(0, 1.0)

# 232
ax[0, 1].errorbar([1, 2, 3], [20, 30, 36], xerr=2, ecolor='#4daf4a', elinewidth=2, fmt='s', label='ETN')
ax[0, 1].legend(loc=3, fancybox=True, shadow=True, fontsize=10, borderaxespad=0.4)
ax[0, 1].set_ylim(10, 40)
ax[0, 1].set_xlim(-2, 6)
ax[0, 1].grid(ls=':', lw=1, color='grey', alpha=0.5)

# 233
x3 = np.arange(1, 10, 0.5)
y3 = np.cos(x3)
ax[0, 2].stem(x3, y3, basefmt='r-', linefmt='b-.', markerfmt='bo', label='life signal')
ax[0, 2].legend(loc=2, fontsize=8, frameon=False, borderpad=0.0, borderaxespad=0.6)
ax[0, 2].set_xlim(0, 11)
ax[0, 2].set_ylim(-1.1, 1.1)

# 234
x4 = np.linspace(0, 2*np.pi, 500)
x4_1 = np.linspace(0, 2*np.pi, 1000)
y4 = np.cos(x4)*np.exp(-x4)
y4_1 = np.sin(2*x4_1)
line1, line2, = ax[1, 0].plot(x4, y4, 'k--', x4_1, y4_1, 'r-', lw=2)
ax[1, 0].legend((line1, line2), ('energy', 'patience'), loc='upper center', fontsize=8, ncol=2, framealpha=0.3,
                mode='expand', columnspacing=2, borderpad=0.1)
ax[1, 0].set_ylim(-2, 2)
ax[1, 0].set_xlim(0, 2*np.pi)

# 235
x5 = np.random.rand(100)
ax[1, 1].boxplot(x5, vert=False, showmeans=True, meanprops=dict(color='g'))
ax[1, 1].set_yticks([])
ax[1, 1].set_xlim(-1.1, 1.1)
ax[1, 1].set_ylabel("Micro SD Card")
ax[1, 1].text(-1.0, 1.2, 'net weight', fontsize=20, style='italic', weight='black', family='monospace')

# 236
mu = 0.0
sigma = 1.0
x6 = np.random.randn(10000)
n, bins, patches = ax[1, 2].hist(x6, bins=30, histtype='stepfilled', cumulative=True, density=True,
                                 color='cornflowerblue', label='Test')
y = ((1/(np.sqrt(2*np.pi)*sigma))*np.exp(-0.5*(1/sigma*(bins-mu))**2))
y = y.cumsum()
y /= y[-1]
ax[1, 2].plot(bins, y, 'r--', linewidth=1.5, label='Theory')
ax[1, 2].set_ylim(0.0, 1.1)
ax[1, 2].grid(ls=":", lw=1, c='grey', alpha=0.5)
ax[1, 2].legend(loc='upper left', fontsize=8, shadow=True, framealpha=0.8)
plt.subplots_adjust()

plt.show()

  • 在子区subplot(231)中,我们绘制了包含误差棒的柱状图,而且柱状图带有“斜线”的几何图案。误差棒的方向是垂直x轴的,误差棒之间使用虚线连接。
  • 在子区subplot(232)中,我们绘制了水平方向的误差棒。同时,使用关键字参数ecolorelinewidth调整了误差棒的颜色和线宽。我们将图例放在左下角,而且借助关键字参数borderaxespad将图例与坐标轴的空白距离进行调整。图例的外边框使用圆角形式进行展示。使用实例方法grid()调整了线条样式、线宽、线条颜色和网格透明度的网格线,以求凸显误差棒的度量精度。
  • 在子区subplot(233),我们绘制了棉棒图,同时调整了棉棒图的组成元素的样式属性值。 我们将图例放在左上角,而且使用关键字参数framen将图例的边界框去掉。调整图例内部的空白距离和图例与坐标轴之间的空白距离。
  • 在子区subplot(234)中, 我们使用实例方法plot()同时绘制了两条折线,而且对折线的颜色、线型和线宽进行了调整。使用变量line1 和line2,用来存储实例Line2D 组成的列表里的实例Line2D元素。在图例中,我们将实例line1和实例line2与图例条目文本内容对应放在实例方法legend()中,同时使用关键字参数framealpha调整了图例背景的透明度,而且使用关键字参数mode将图例中的条目文本并排水平放置。
  • 在子区subplot(235)中,我们绘制了水平放置的箱线图,同时向图中添加了文本内容作为注释,文本内容简单地进行了文本样式和字体的调整。
  • 在子区subplot(236)中,我们绘制了累积(cumulative=True)的阶梯填充型直方图,而且用频率或者称为密度的数值(density=True才行 normed=True会报错 )进行直方图高度的标示。在此基础上,绘制了正态分布的根率密度曲线。

共享绘图区域坐标轴(移动坐标轴)

1.一个区域,左右两边都有纵坐标

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False

fig, ax1 = plt.subplots()
t = np.arange(0.05, 10.0, 0.01)
s1 = np.exp(t)
ax1.plot(t, s1, c='b', ls='-')
ax1.set_xlabel('x坐标轴')
ax1.set_ylabel('以e为底指数函数', c='b')
ax1.tick_params('y', colors='b')

ax2 = ax1.twinx()
s2 = np.cos(t**2)
ax2.plot(t, s2, c='r', ls=':')
ax2.set_ylabel("余弦函数", c='r')
ax2.tick_params('y', colors='r')

plt.show()

使用ax1.set_ylabel()ax1.tick_params()实例方法将y轴标签、主刻度线和刻度标签都设置成蓝色。调用实例方法ax1.twinx()生成实例ax2,此时实例ax2的x轴与实例ax1的x轴是共享的,实例ax2的刻度线和刻度标签在右侧轴脊处绘制。

2.在子区域里共享坐标轴

调用签名使用subplots( 1,2,sharey=True)的形式,其中参数sharey表示子区1和子区2共享y坐标轴。相对应的,还可以设置参数sharex的取值形式。具体而言,参数sharex和参数sharey的取值形式有四种,分别是row、col、all和none, 其中all和none分别等同于“True” 和“False”。 下面我们参数sharey的取值形式与使用方法和参数sharex完全相同,不赘述。
先放一张原始的图:

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False

x1 = np.linspace(0, 2*np.pi, 400)
y1 = np.cos(x1**2)
x2 = np.linspace(0.01, 10, 100)
y2 = np.sin(x2)
x3 = np.random.rand(100)
y3 = np.linspace(0, 3, 100)
x4 = np.arange(0,  6, 0.5)
y4 = np.power(x4, 3)

fig, ax = plt.subplots(2, 2)
ax1 = ax[0, 0]
ax1.plot(x1, y1)
ax1 = ax[0, 1]
ax1.plot(x2, y2)
ax1 = ax[1, 0]
ax1.scatter(x3, y3)
ax1 = ax[1, 1]
ax1.scatter(x4, y4)

plt.show()

plt.subplots(2, 2)加上sharex=‘all‘的效果,会让横坐标变得统一。而且横坐标是取子区域里最大的那个。

plt.subplots(2, 2,sharex='all')

plt.subplots(2, 2,sharex='col')   # 每一列都以这一列里的取值范围上线为共享范围,如下图
plt.subplots(2, 2,sharex='row')   # 每一行都以这一行里的取值范围上线为共享范围,就不放图了 


当然还可以有办法把子图间的空隙去掉,plt.subplots_adjust(hspace=0)就是去除水平方向空隙。(代码放在设置共享坐标的下面)

3.移动坐标轴的

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False

x = np.linspace(-2*np.pi, 2*np.pi, 200)
y = np.sin(x)
y2 = np.cos(x)
ax = plt.subplot(111)
plt.plot(x, y, ls='-', lw=2, label='$sin(x)$')
plt.plot(x, y2, ls='-', lw=2, label='$cos(x)$')
plt.legend(loc='lower left')
plt.xlim(-2*np.pi, 2*np.pi)
plt.xticks([-2*np.pi, -3*np.pi/2, -1*np.pi, -1*np.pi/2, 0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi],
           [r"$-2\pi$", r"$-3\pi/2$", r"$-\pi$", r"$-2\pi/2$", r"$0$", r"$pi/2$", r"$\pi$", r"$3\pi/2$", r"$2\pi$"])
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_position(('data', 0))
ax.spines['left'].set_position(('data', 0))
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
plt.show()

代码主体部分,我们主要调用前面章节的代码内容,在此基础上,我们添加了两条关键代码:
ax.spines['bottom'].set_position(('data', 0))
ax.spines['left'].set_position(('data', 0))
ax.spines会调用轴脊字典,其中的键是轴脊位置,如”top““right”“bottom”“left”键值是matplotlib.spines.Spine对象,实例方法set position()就是对轴脊位置的控制方法,其中参数“data”说明控制轴脊位置的坐标值与折线图的坐标系统一致。 因此,参数0就表示将底端轴脊移动到左侧轴脊的零点处。同理,将左侧轴脊移动到底端轴脊的零点处。在matplotib元素组成结构中,已经说明轴脊是刻度线和刻度标签的载体。这样,当左侧和底端轴脊移动位置时,刻度线和刻度标签也会相应的移动位置。我们将x轴刻度线放在底端轴脊上,将y轴刻度线放在左侧轴脊上。从而,完成移动坐标轴位置的工作。

标题、标签、图例

0.matplotlib自带的TeX功能

用Tex对文本内容进行渲染,通过使用r"$$"模式,将表达式\sin和\cos嵌入一对美元符号之间。在“r"$text1\text2$"”中的非数学表达式文本text1会以斜体形式输出,并且最终输出时就会呈现印刷级别的文档效果。需要说明的是,在字符串r"$text1\text2$" 的开始之处有一个标记 “r” 表示该字符串是raw strings,字符串按照TeX规范进行解析。

1.添加图列legend()

bbox_to_anchor线框位置参数:四元元组,Axes坐标系统。第1个元素代表距离画布左侧的x轴长度的倍数的距离;第2个元素代表距离画布底部的y轴长度的倍数的距离;第3个元素代表x轴长度的倍数的线框长度;第4个元素代表y轴长度的倍数的线框宽度。代码中的语句legend(bbox_ to_ anchor-=(0.05,0.95))将图例放在距离坐标轴左边0.1、底部7.6的位置

loc位置参数:不仅可以用字符串表示,还可以用对应的数字表示。字符串的字面意思可以理解放的位置。

位置的字符串参数 位置的数字参数
upper right 1
upper left 2
lower left 3
lower right 4
center left 6
center right 7
lower center 8
upper center 9
center 10

shadow:线框是否添加阴影。
fancybox:线框圆角或直角。
ncol图列里一行放几个参数,这里一共三个,三个也就放的一行。ncol=1,那么就会竖着放。

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False

x = np.arange(0, 2.1, 0.1)
y = np.power(x, 3)
y1 = np.power(x, 2)
y2 = np.power(x, 1)

plt.plot(x, y, ls='-', lw=2, label='$x^3$')
plt.plot(x, y1, ls='-', lw=2, label='$x^2$')
plt.plot(x, y2, ls='-', lw=2, label='$x^1$')

plt.legend(loc='upper left', bbox_to_anchor=(0.05, 0.95), ncol=3, title='power function', shadow=True, fancybox=True)

plt.show()

下面是ncol=1:

2.添加标题title()

关键字参数主要集中在标题位置参数和标题文本格式参数:
标题位置参数值有”left”“center”和“right”。
标题文本格式参数主要是字体类别(family)字体大小(size)字体颜色( color)、字体风格(style)等,这些文本格式参数可以放在关键字参数fontdict的字典中存储,也可以分别作为标题函数title()的关键字参数。

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-2, 2, 1000)
y = np.exp(x)

plt.plot(x, y, ls='-', lw=2)

plt.title('center demo')
plt.title('left demo', loc='left', fontdict={
                                     'size': 'xx-large',
                                     'color': 'r',
                                     'family': 'Time New Roman'})
plt.title('right demo', loc='right', family='Comic Sans MS', size=20, style='oblique', color='c')

plt.show()

图里的left demo因为没找到这个字体所以默认的。

3.调节刻度范围xlim()和刻度标签xticks()

通过调用xlim()函数来改变x轴的刻度范围。
又通过函数xticks()来改变刻度标签。

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-2*np.pi, 2*np.pi, 200)
y = np.sin(x)

plt.subplot(211)
plt.plot(x, y)

plt.subplot(212)
plt.xlim(-2*np.pi, 2*np.pi)
plt.xticks([-2*np.pi, -3*np.pi/2, -1*np.pi, -1*np.pi/2, 0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi],
           [r"$-2\pi$", r"$-3\pi/2$", r"$-\pi$", r"$-2\pi/2$", r"$0$", r"$pi/2$", r"$\pi$", r"$3\pi/2$", r"$2\pi$"])
plt.plot(x, y)

plt.show()

4.逆序设置坐标轴标签xlim()

通过使用函数xlim()实现将“使用年限”的刻度标签值降序排列,其中的关键是将函数xlim(xmin,xmax)的参数xmin和xmax调换顺序,进而变成xlim(xmax,xmin)实现效果。

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
mpl.rcParams['font.sans-serif'] = ['FangSong']
mpl.rcParams['axes.unicode_minus'] = False

time = np.arange(1, 11, 0.5)
machinePower = np.power(time, 2)+0.7

plt.plot(time, machinePower, linestyle='-', linewidth='2', c='r')
plt.xlim(10, 1)
plt.xlabel('使用年限')
plt.ylabel('机器功率')

plt.title('机器损耗曲线')

plt.grid(ls=':', lw=1, c='gray', alpha=0.5)

可以直观清晰地反映出机器的性能随着使用年限的推移而产生的下降情况。

设置xy轴数值显示范围

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0.05, 10, 1000)  # 函数在0.05到10之间均匀地取1000个数
y = np.random.rand(1000)

plt.scatter(x, y, c='g')  # 绘制散点图,c标记散点图颜色
plt.xlabel('x-axis')  # 设置x轴标签文本
plt.ylabel('y-axis')  # 设置y轴标签文本
plt.legend()
plt.xlim(0.05, 5)  # 设置x轴的数值显示范围
plt.ylim(0, 0.5)  # 设置y轴的数值显示范围
plt.show()


文章作者: 易百分
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 易百分 !
  目录