1. Matplotlib基础内容

一. Matplotlib基础知识

通常情况下,我们可以将一副Matplotlib图像分成三层结构:

  • 第一层是底层的容器层,主要包括Canvas(画板)、Figure(画布、图片)、Axes(图表); 一个axes代表一个图表,包含一个plot,一个figure代表一张画布绘制一张图片,一张图片或一张画布可以有多个图表;canvas画板,摆放画布的工具。关系:画板→画布或图片→线条、饼图等图片;
  • 第二层是辅助显示层,主要包括Axis(坐标轴)、Spines(绘图区边框线)、Tick(坐标刻度)、Grid(网格)、Legend(图例)、Title(标题)等,该层可通过set_axis_off()或set_frame_on(False)等方法设置不显示;
  • 第三层是图像层,即通过plot、contour、scatter等方法绘制的图像。

Matplotlib绘制图表的构成如下图所示:
在这里插入图片描述

(一)底层容器层

容器层主要由Canvas、Figure、Axes组成:

  • Canvas是位于最底层的系统层,在绘图的过程中充当画板的角色,即放置画布的工具。通常情况下,我们并不需要对Canvas特别的声明,但是当我需要在其他模块如PyQt中调用Matplotlib模块绘图时,就需要首先声明Canvas,这就相当于我们在自家画室画画不用强调要用画板,出去写生时要特意带一块画板。
  • Figure是Canvas上方的第一层,也是需要用户来操作的应用层的第一层,在绘图的过程中充当画布的角色。当我们对Figure大小、背景色彩等进行设置的时候,就相当于是选择画布大小、材质的过程。因此,每当我们绘图的时候,写的第一行就是创建Figure的代码
  • Axes是应用层的第二层,在绘图的过程中相当于画布上的绘图区的角色。一个Figure对象可以包含多个Axes对象,每个Axes都是一个独立的坐标系,绘图过程中的所有图像都是基于坐标系绘制的。
    在这里插入图片描述

1. 画布Figure

在Matplotlib中,整个图表是一个figure对象。我们可以用plt.figure创建一个新的Figure,创建完之后会弹出一个空窗口。figure函数的调用方式如下:

matplotlib.pyplot.figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, frameon=True, FigureClass=<class'matplotlib.figure.Figure'>, **kwargs)

主要参数说明:

参数 属性 描述
num 整数或字符串,可选参数 Num=n 选择图表 n 或创建图表 n
figsize 二维元组 创建指定大小的图像,单位:尺寸
dpi 整数值 每英寸的像素数,默认 80
facecolor 字符串 背景颜色
edgecolor 字符串 边框颜色
frameon 布尔值 是否显示边框

plt.figure有一些选项,特别是figsize,它用于确保当图片保存到磁盘时具有一定大小和横纵比,通过plt.gcf()函数即可得到当前Figure的引用。

(1)plt.subplot()

Figure只是弹出一个空白的窗口,不能通过Figure绘图,必须使用subplot()函数创建一个或多个subplot才行,如下示例:

ax1 = plt.subplot(2,2,1)

这条代码的意思是:创建的2×2的subplot,且当前选中的是4个subplot中的第一个(编号从1开始)。

subplot函数的具体调用方式如下:

matplotlib.pyplot.subplot(*args, **kwargs)

在一个图表中绘制多个子图时,此函数调用时传递的参数如下:

matplotlib.pyplot.subplot(nrows, ncols, plot_number, axisbg, polar, projection)

参数说明如下:

参数 描述
nrows nrows 表示图的行数
ncols ncols 表示图的列数
plot_number plot_number 表示第几个子图
axisbg axisbg=color,表示所选子图背景颜色
polar polar=False,是否为极地投影,默认值为False
projection 使用指定的投影方式,该方式使用之前需要已经注册(registered)

绘图区分为 nrows 行和 ncols 列,从左到右、从上到下顺序对每个区域进行编号,左上区编号为 1。上述三个参数均小于 10 时,中间逗号可以省略,也可以保留。例如:

import matplotlib.pyplot as plt
import numpy as np
from numpy.random import randn

plt.Figure()
ax1 = plt.subplot(2,2,1)
ax2 = plt.subplot(2,2,2)
ax3 = plt.subplot(2,2,3)
ax1.hist(randn(100), bins=20, color='k', alpha=0.3)
ax2.scatter(np.arange(30), np.arange(30)+3*randn(30))
ax3.plot(randn(50).cumsum(), 'k--')
plt.show()

在这里插入图片描述

(2)plt.subplots()

另外,我们也可以使用plt.subplots()函数,它可以创建一个新的Figure,并返回一个包含已创建的subplot对象的Numpy数组,可以轻松地对axes数组进行索引,就好像一个二维数组一样。如果用 subplots 创建了多个子图,那么 axes 就是一个列表,用索引列表元素的方法就能获取到每一个 axes,所以 axes 也能够写入循环中。plt.subplots()调用格式如下:

matplotlib.pyplot.subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True, subplot_kw=None, gridspec_kw=None, **fig_kw)

参数说明如下:

参数 属性 描述
nrows 整数 subplot 网格行数,默认值为1
ncols 整数 subplot 网格列数,默认值为1
sharex 布尔参量或字符串(“row”, “col”, “all”, 或“none”) 若为 True:对所有子图共用 x 轴(最后一行除外),'all’等同于 True;‘None’等同于 False;若为‘col’每列子图共享 x 轴;若为’row’每行子图共享 x 轴
sharey 布尔参量或字符串(“row”, “col”, “all”, 或“none”) 若为 True:对所有子图共用 y 轴(最后一行除外),'all’等同于 True;‘None’等同于 False;若为‘col’每列子图共享 y 轴;若为’row’每行子图共享 y 轴
squeeze 布尔参量 若为 True,额外维度被剔除:若为 False,没有改变,返回二维数组
subplot_kw 字典数据 查询 add_subplot()
fig_kw 字典数据 figure()

在默认情况下,matplotlib会在subplot外围留下一定的边距,并在subplot之间留下一定的间距,间距与图像的高度和宽度有关,如果你调整了图像的大小其间距也会调整。我们可以利用Figure的subplot_adjust()函数可以轻而易举地修改间距。

matplotlib.pyplot.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)

各个参数取值范围为[0-1]。wspace和hspace用于控制宽度和高度的百分比,可以用作subplot之间的间距调整。例如:

import matplotlib.pyplot as plt
from numpy.random import randn

fig, axes = plt.subplots(2,2,sharex=True,sharey=True)
for i in range(2):
    for j in range(2):
        axes[i,j].hist(randn(50),bins=50,color='k',alpha=0.5)
plt.subplots_adjust(wspace=0,hspace=0)
plt.show()

在这里插入图片描述

(3)fig.add_subplot()

通常我们创建图形时,首先会用 fig = plt.figure() 创建一个 “画板”,并定义画板名称为 fig,此时画板是空白的,通过 ax = fig.add_subplot() 向画板中添加新的画布,并为画布指定名字为 “ax”,然后就可以单独给这个画布设置各种属性了。例如:

import matplotlib.pyplot as plt
import numpy as np
from pandas import Series

data = Series([1.47,1.62,1.78,1.94,2.38,2.60],index=['2012','2013','2014','2015','2016','2017'])
fig = plt.figure(facecolor='w')
ax1 = fig.add_subplot(111)
ax1.plot(data,label='income', color = 'r', linestyle=':',  marker = 's')
ax1.set_title('Income chart')
ax1.set_xlabel('Year')
ax1.set_ylabel('Income')
ax1.annotate('Largest point',xy=(5,2.60),xytext=(3,2.5), arrowprops=dict(arrowstyle='->'))
plt.show()

在这里插入图片描述

当我们利用 add_subplot() 函数绘制多幅子图时,分别定义每个子图。例如:

import matplotlib.pyplot as plt
import numpy as np

x1 = np.arange(1, 6)
x2 = np.arange(1, 11)
y1 = x1 ** 2
y2 = x1 ** 3
y3 = x2 ** 2
# create figure and axes
fig = plt.figure()
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(212)
ax1.bar(x1, y1)
ax2.scatter(x1, y2)
ax3.plot(x2, y3)
plt.show()

在这里插入图片描述

2. 图表Axes

在这里插入图片描述

Axis 指 x、y 坐标轴等(如果有三维那就还有 z 轴),代表的是 “坐标轴”。而 Axes 在英文里是 Axis 的复数形式,也就是说 axes 代表的其实是 figure 当中的一套坐标轴。之所以说一套而不是两个坐标轴,是因为如果你画三维的图,axes 就代表 3 根坐标轴了。所以,在一个 figure 当中,每添加一次 subplot ,其实就是添加了一套坐标轴,也就是添加了一个 axes,放在二维坐标里就是你添加了两根坐标轴,分别是 x 轴和 y 轴。所以当你只画一个图的时候,plt.xxx 与 ax.xxx 其实都是作用在相同的图上的。

简言之,figure 是作图时的一个大画板,而 axes 是在这个画板上的很多幅画布(子图),绘制的所有图都在画布(axes)上。例如下面这副漫画,定义 4 个 subplot,自然就有 4 个Axes
在这里插入图片描述

很多地方说 plt.plot()plt.scatter()plt.bar(),其实本质上还是在 axes 上画图,可以将他们理解为:先在 figure(画板)上获取一个当前要操作的 axes(画布),如果没有 axes 就自动创建一个并将其设为当前的 axes,然后在当前这个 axes 上执行各种绘图功能。

(二)辅助显示层

辅助显示层显示Axes内除了根据数据绘制出的图像以外的内容,主要包括外观(facecolor)、边框线(spines)、坐标轴(axis)、坐标轴名称(axis label)、坐标轴刻度(tick)、坐标轴刻度标签(tick label)、网格线(grid)、图例(legend)、标题(title)等内容。该层的设置可使图像显示更加直观更加容易被用户理解,但又并不会对图像产生实质的影响。
在这里插入图片描述

1. 标题Title

(1)plt.title()

Matplotlib中设置图表标题的函数是plt.title(),该函数的调用方式如下:

matplotlib.pyplot.title(label, fontdict=None, loc=None, pad=None, *, y=None, **kwargs)

参数说明如下:

参数 属性 描述
label 字符串 标题文本
fontdict 字典类型 控制文本的字体属性
loc 取值范围为{'left', 'center', 'right'} 控制标题的位置,默认值为rcParams["axes.titlelocation"]'center'
y 浮点数 设置标题在子图中的垂直距离,单位为%1.0代表在子图最顶部,None则自动确定标题位置,避免与其他元素重叠。默认值为rcParams["axes.titley"] (None)
pad 浮点数 设置标题与子图的填充距离(内边距),默认值为default: rcParams["axes.titlepad"] (6.0)
**kwargs Text 对象关键字属性 用于控制文本的外观属性,如字体、文本颜色等

上述参数中,fontdict的默认值为:

{
    
    'fontsize': rcParams['axes.titlesize'],
 'fontweight': rcParams['axes.titleweight'],
 'color': rcParams['axes.titlecolor'],
 'verticalalignment': 'baseline',
 'horizontalalignment': loc}

例如:绘制心形线

import matplotlib.pyplot as plt
import numpy as np

t = np.linspace(0, np.math.pi, 1000)
x = np.sin(t)
y = np.cos(t) + np.power(x, 2.0 / 3)
plt.plot(x, y, color='red', linewidth=2)
plt.plot(-x, y, color='red', linewidth=2)
plt.title("Heart", fontdict={
    
    'fontsize': 15, 'color': 'darkgreen',}, pad=15)
plt.ylim(-2, 2)
plt.xlim(-2, 2)
plt.show()

在这里插入图片描述

(2)plt.suptitle()

plt.suptitle() 函数用于设置整个Figure的标题,该函数的调用格式如下:

matplotlib.pyplot.suptitle(t, **kwargs)

函数主要参数如下:

参数 属性 描述
t 字符串类型 设置标题文本
x 浮点数 设置标题在图像水平方向相对位置,默认值为0.5
y 浮点数 设置标题在图像垂直方向相对位置,默认值为0.98
fontdict 字典类型 控制文本的字体属性
horizontalalignment(缩写ha 字符串类型,取值范围{'center', 'left', right'} 设置相对于(x,y)的水平方向对齐方式,默认值为'center'
verticalalignment(缩写va 字符串类型,取值范围{'top', 'center', 'bottom', 'baseline'} 设置相对于(x,y)的垂直方向对齐方式,默认值为'top'
fontsize(缩写size 浮点数或{'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'} 设置文本的字体大小,默认值为rcParams["figure.titlesize"] ('large')
fontweight(缩写weight 0-1000的整数或{'ultralight', 'light', 'normal', 'regular', 'book', 'medium', 'roman', 'semibold', 'demibold', 'demi', 'bold', 'heavy', 'extra bold', 'black'} 设置文本的字重
**kwargs Text 对象关键字属性 用于控制文本的外观属性,如字体、文本颜色等

例如:绘制三角函数Sine、Cosine和Tangent的图形

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

mpl.rcParams['font.sans-serif'] = ['KaiTi']
plt.rcParams["font.family"]="sans-serif"
mpl.rcParams['axes.unicode_minus'] = False
x = np.arange(-0.49 * np.pi, 0.49 * np.pi, 0.01)
y_sin = np.sin(x)
y_cos = np.cos(x)
y_tan = np.tan(x)
# 绘制正弦图
plt.subplot(2,  2,  1)
plt.plot(x, y_sin, "--")
plt.title('Sine')
# 绘制余弦图
plt.subplot(2,  2,  2)
plt.plot(x, y_cos, "--")
plt.title('Cosine')
# 绘制正切图
plt.subplot(2,  2,  3)
plt.plot(x, y_tan, "--")
plt.title('Tangent')
# 设置Figure的标题
plt.suptitle('三角函数图')
plt.subplots_adjust(wspace=0.3, hspace=0.3)
# 展示图像
plt.show()

在这里插入图片描述

2. 网格线Grid

设置网格所调用的方法格式如下:

matplotlib.pyplot.grid(b=None, which='major', axis='both', color, linestyle, linewidth, **kwargs)

参数说明如下:

参数 属性 描述
b 布尔值或[‘on’,‘off’] 表示网格是否开启
which 取值为’major’、‘minor’和’both’ 默认为’major’,可以显示网格,而当该值为’minor’时,只有白画板,没有网格
axis 取值为‘both’、‘x’和‘y’ 默认值为‘both’,选择使用网格的数轴
color 可以用c来代替color 设置网格线的颜色
linestyle 可以用ls来代替linestyle 设置网格线的风格,可以是连续实线,虚线或者其它不同的线条
linewidth 可以用lw来代替linewidth 设置网格线的宽度

例如:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-np.pi,np.pi,100)
y = np.sin(x)
plt.grid(b='on', which='major', axis='y', c='#5684ae', ls='dashed', lw=0.5)
plt.plot(x, y)
plt.title('Sine')
plt.show()

在这里插入图片描述

3. 坐标轴范围Axis

坐标轴的范围有多个函数可以调用设置。

(1)plt.axis()
matplotlib.plt.axis(*args, emit=True, **kwargs)

该函数的参数是x轴和y轴的最大值和最小值,其传参方式有如下四种:

  • xmin, xmax, ymin, ymax = axis()
  • xmin, xmax, ymin, ymax = axis([xmin, xmax, ymin, ymax])
  • xmin, xmax, ymin, ymax = axis(option)
  • xmin, xmax, ymin, ymax = axis(**kwargs)

也就是说要么不传任何参数,要么就以列表形式传递四个坐标轴的界限值,或者传递布尔值或特殊字符串。可传递的特殊字符串如下所示:

======== ==========================================================
Value    Description
======== ==========================================================
'on'     Turn on axis lines and labels. Same as ``True``.
'off'    Turn off axis lines and labels. Same as ``False``.
'equal'  Set equal scaling (i.e., make circles circular) by
         changing axis limits.
'scaled' Set equal scaling (i.e., make circles circular) by
         changing dimensions of the plot box.
'tight'  Set limits just large enough to show all data.
'auto'   Automatic scaling (fill plot box with data).
'normal' Same as 'auto'; deprecated.
'image'  'scaled' with axis limits equal to data limits.
'square' Square plot; similar to 'scaled', but initially forcing
         ``xmax-xmin = ymax-ymin``.
======== ==========================================================

例如:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-np.pi,np.pi,100)
y = np.cos(x)
plt.subplot(2,2,1)
plt.axis()
plt.plot(x, y, '.g')
ax2 = plt.subplot(2,2,2)
plt.axis([-np.pi, np.pi, -1, 1])
plt.plot(x, y, '-c')
ax3 = plt.subplot(2,2,3)
plt.axis('off')
plt.plot(x, y, 'y')
ax4 = plt.subplot(2,2,4)
plt.axis('equal')
plt.plot(x, y, '-.')
plt.show()

在这里插入图片描述

(2)plt.figure()
plt.figure(figsize=(a,b))

其中a和b分别是x刻度比例和y刻度比例。例如:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-np.pi,np.pi,100)
y = np.sqrt(x)
plt.figure(figsize=(25,5))
plt.plot(x,y)
plt.show()

在这里插入图片描述

(3)plt.xlim()和plt.ylim()
matplotlib.plt.xlim(*args, **kwargs)
matplotlib.plt.ylim(*args, **kwargs)

上述函数xlim()和ylim()分别设置x轴和y轴的坐标轴界限。例如:

import matplotlib.pyplot as plt
import numpy as np

def f(t):
    return np.exp(-t) * np.cos(2*np.pi*t)
x1 = np.arange(0.0, 10.0, 0.1)
x2 = np.arange(0.0, 10.0, 0.02)
plt.xlim(0,10)
plt.ylim(-1,1)
plt.plot(x1, f(x1), 'bo', x2, f(x2), 'k')
plt.show()

在这里插入图片描述

(4)ax.set_xlim()和ax.set_ylim()
set_xlim(self, left=None, right=None, emit=True, auto=False, *, xmin=None, xmax=None)
set_ylim(self, bottom=None, top=None, emit=True, auto=False, *, ymin=None, ymax=None)

set_xlim()和set_ylim()分别设置x轴和y轴的坐标轴界限。例如:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0.0, 100.0, 0.02)
ax = plt.subplot(111)
ax.set_xlim(0,10)
plt.plot(x, np.cos(2*np.pi*x), 'r--')
plt.show()

在这里插入图片描述

4. 坐标轴标签Lable

设置坐标轴标签所调用的方法格式如下:

# x轴标签
matplotlib.pyplot.xlabel(xlabel, fontdict=None, labelpad=None, *, loc=None, **kwargs)
# y轴标签
matplotlib.pyplot.ylabel(ylabel, fontdict=None, labelpad=None, *, loc=None, **kwargs)

参数说明如下:

参数 属性 描述
xlabel / ylabel 字符串 控制坐标轴标签文本
fontdict 字典数据 控制文本的字体属性
labelpad 浮点数 设置标签与子图的填充距离(内边距),默认值为default: rcParams["axes.titlepad"] (6.0)
loc 取值范围为{'left', 'center', 'right'} 控制标题的位置,默认值为center

例如:绘制正弦曲线

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

mpl.rcParams['font.sans-serif'] = ['KaiTi']
mpl.rcParams['font.serif'] = ['KaiTi']
mpl.rcParams['axes.unicode_minus'] = False
x = np.arange(-0.49 * np.pi, 0.49 * np.pi, 0.01)
y = np.tan(x)
plt.plot(x, y)
plt.title("function y=tan(x)", fontsize=15, pad=10)
plt.xlabel("自变量", fontsize=10, labelpad=10)
plt.ylabel("正弦值", fontsize=10)
plt.tick_params(axis='both', labelsize=10)
plt.show()

在这里插入图片描述

5. 坐标轴刻度Tick

设置坐标轴刻度所调用的方法格式如下:

# x轴标签刻度
matplotlib.pyplot.xticks(ticks=None, labels=None, **kwargs)
# y轴标签刻度
matplotlib.pyplot.yticks(ticks=None, labels=None, **kwargs)

参数说明如下:

参数 属性 描述
ticks 列表数据 传递刻度位置的列表
labels 列表数据,可选参数 放置在对应刻度线位置上的标签
**kwargs 控制刻度标签的属性

例如:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-np.pi, np.pi, 128, endpoint=True)
cosx, sinx, x_3 = np.cos(x), np.sin(x), x / 3
plt.xlim(x.min() * 1.2, x.max() * 1.2)
plt.ylim(cosx.min() * 1.2, cosx.max() * 1.2)
plt.plot(x, cosx, color='g', linewidth=2.0, linestyle='--')
plt.plot(x, x_3, color='c', linewidth=1.0, linestyle='-')
new_ticks = np.linspace(-2, 2, 11)
plt.xticks([-np.pi, -np.pi / 2, 0, np.pi / 2, np.pi], [r'$-\pi$', r'$-\frac{\pi}{2}$', 0, r'$+\frac{\pi}{2}$', r'$+\pi$'])
plt.yticks([-1, 0, 1], [r'-1', r'0', r'+1'])
plt.xlabel('X-values')
plt.ylabel('Y-values')
plt.show()

在这里插入图片描述

以上面的例子为例,我们聊聊通过实例化Figure和Axes之后绘图时设置刻度与通过plt.xxx()直接绘图时设置刻度的区别。先来看看下面的代码:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-np.pi, np.pi, 128, endpoint=True)
cosx, sinx, x_3 = np.cos(x), np.sin(x), x / 3
fig = plt.figure(1)
ax1 = plt.subplot(111)
line1, line2 = ax1.plot(x, cosx, 'g', x, x_3, 'c')
line1.set_linewidth(2)
line2.set_linewidth(1)
line1.set_linestyle('--')
line2.set_linestyle('-')
ax1.set_xlim(x.min() * 1.2, x.max() * 1.2)
ax1.set_ylim(cosx.min() * 1.2, cosx.max() * 1.2)
ax1.set_xticks([-np.pi, -np.pi / 2, 0, np.pi / 2, np.pi])
ax1.set_xticklabels([r'$-\pi$', r'$-\frac{\pi}{2}$', 0, r'$+\frac{\pi}{2}$', r'$+\pi$'])
ax1.set_yticks([-1, 0, 1])
ax1.set_yticklabels([r'-1', r'0', r'+1'])
ax1.set_xlabel('X-values')
ax1.set_ylabel('Y-values')
plt.show()

上述代码可以绘制得到同一幅图表,只是我们在设置刻度时调用set_xticks()和set_xticklabels()两个函数设置分别设置刻度位置与刻度位置上对应的标签。

我们现在尝试将上图的图表内容绘制在一个平面直角坐标系中,此时我们需要修改坐标轴刻度的位置:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-np.pi, np.pi, 128, endpoint=True)
cosx, sinx, x_3 = np.cos(x), np.sin(x), x / 3
plt.xlim(x.min() * 1.2, x.max() * 1.2)
plt.ylim(cosx.min() * 1.2, cosx.max() * 1.2)
plt.plot(x, cosx, color='g', linewidth=2.0, linestyle='--')
plt.plot(x, x_3, color='c', linewidth=1.0, linestyle='-')
new_ticks = np.linspace(-2, 2, 11)
plt.xticks([-np.pi, -np.pi / 2, 0, np.pi / 2, np.pi], [r'$-\pi$', r'$-\frac{\pi}{2}$', 0, r'$+\frac{\pi}{2}$', r'$+\pi$'])
plt.yticks([-1, 0, 1], [r'-1', r'', r'+1'])

# 获取当前图表
ax = plt.gca()
# 把右边和上边的边框去掉
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
# 把x轴的刻度设置为‘bottom',把y轴的刻度设置为 ’left‘
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
# 设置bottom和left对应到0点
ax.spines['bottom'].set_position(('data',0))
ax.spines['left'].set_position(('data',0))

plt.show()

在这里插入图片描述

6. 图例Legend

设置图表中的图例可以调用函数plt.legend(),该函数的格式如下:

matplotlib.pyplot.legend(*args, **kwargs)

可传递的参数说明如下:

参数 属性 描述
handles 列表数据 设置所要处理的线
labels 列表数据 设置所要处理的线的图例名称
loc 字符串或元组数据 设置图例位置
prop 设置图例字体参数
fontsize 整数 设置图例字体大小
markerscale 浮点数 设置图例标记与原始标记的相对大小
markerfirst 布尔值,默认值为True 设置图例标记与图例标签的相对位置,如果值为True,则图例标记位于图例标签的左侧
numpoints 整数 为线条图图例条目创建标记点数
scatterpoints 整数 为散点图图例条目创建标记点数
scatteryoffsets 整数 为散点图图例条目创建标记的垂直偏移量
frameon 布尔值,默认值为True 控制是否应在图例周围绘制框架
fancybox 布尔值 控制是否应在构成图例背景的FancyBboxPatch周围启用圆边
shadow 布尔值,默认值为False 控制是否在图例后面画一个阴影
framealpha 浮点数 控制图例框架的 Alpha 透明度
edgecolor 字符串 控制图例框架的边框颜色
facecolor 字符串 控制图例框架的背景颜色
ncol 整数数值,默认值为1 设置图例分为n列展示
borderpad 数值 设置图例边框的内边距
labelspacing 数值 设置图例条目之间的垂直间距
handlelength 数值 设置图例句柄的长度
handleheight 数值 设置图例句柄的高度
handletextpad 数值 设置图例句柄和文本之间的间距
borderaxespad 数值 设置轴与图例边框之间的距离
columnspacing 数值 设置图例列间距
title 字符串 设置图例标题
bbox_to_anchor 指定图例相对于轴的位置
bbox_transform

上述参数中设置图例位置的参数loc的可选值有可选值有{‘best'、‘upper right'、‘upper left'、‘lower left'、‘lower right'、‘right'、‘center left'、‘center right'、‘lower center'、‘upper center'、‘center'}。上述11个可选参数值分别对应了0-10之间的11个数字,因此在传递参数时,loc参数的值也可以传递设置的位置相对应的数字。

例如:

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

mpl.rcParams['font.sans-serif'] = ['SimSun']
mpl.rcParams['font.serif'] = ['SimSun']
mpl.rcParams['axes.unicode_minus'] = False
x = np.linspace(-3, 3, 100)
plt.xlim(-1, 2)
plt.ylim(-2, 3)
plt.xlabel('X Axis', labelpad=8)
plt.ylabel('Y Axis', labelpad=8)
plt.plot(x, 2 * x + 1, color='red', linewidth=1.0, linestyle='--')
plt.plot(x, x ** 2, color='blue', linewidth=2.0, linestyle='-')
plt.xticks(np.linspace(-2, 2, 11))
plt.yticks([-1, 0, 1, 2, 3], ['level1', 'level2', 'level3', 'level4', 'level5'])
plt.legend(labels=['函数:2*x+1','函数:x**2'],loc='lower right', frameon=True, shadow=True )
plt.show()

在这里插入图片描述

7. 边框线Spine

边框线的设置可以调用ax.spines()选择所要设置的边框线,然后进行相应的操作。

  • 设置边框线线宽

    ax.spines['bottom'].set_linewidth('2.0')
    
  • 设置边框线线型

    ax.spines['left'].set_linestyle("--")
    
  • 设置边框线颜色

ax.spines['top'].set_color('none')
  • 设置边框线位置

    ax.spines['bottom'].set_position(('data',0))
    
  • 设置边框线可见与否

    ax.spines['right'].set_visible(False)
    

例如:

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

mpl.rcParams['font.sans-serif'] = ['SimSun']
mpl.rcParams['font.serif'] = ['SimSun']
mpl.rcParams['axes.unicode_minus'] = False
x = np.arange(5)
a = np.random.random(5)
b = np.random.random(5)
c = np.random.random(5)
total_width, n = 0.8, 3
width = total_width / n
x = x - (total_width - width) / 2
plt.bar(x, a,  width=width, label='A')
plt.bar(x + width, b, width=width, label='B')
plt.bar(x + 2 * width, c, width=width, label='C')
plt.legend()
ax = plt.gca()
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_linewidth('2.0')
ax.spines['left'].set_linestyle('--')
ax.spines['right'].set_visible(False)
plt.show()

在这里插入图片描述

8. 文本Text

在Matplotlib中添加文本,可以调用plt.text()函数,其调用格式如下:

matplotlib.pyplot.text(x, y, s, fontdict=None, **kwargs)

参数说明如下:

参数 属性 描述
x, y 浮点数 设置注释文本的数字坐标位置
s 字符串 设置文本内容
fontdict 字典类型,默认为空 用于覆盖默认文本属性的字典项,若字典项为空则默认属性由rcParams确定
**kwargs 设置文本属性

**kwargs可设置的文本属性与参数取值如下:
在这里插入图片描述

9. 注释Annotate

在Matplotlib中添加注释,可以调用plt.annotate()函数,其调用格式如下:

matplotlib.pyplot.annotate(text, xy, *args, **kwargs)

参数说明如下:

参数 属性 描述
s 字符串 设置注释文本的内容
xy 二维元组 设置被注释的坐标点
xytext 二维元组 设置注释文本的坐标点
xycoords 可选值见后面的表格 设置被注释点的坐标系属性
textcoords 除了允许输入xycoords的属性值,还允许输入'offset points'和offset pixels,两者的含义均是“相对于被注释点xy的偏移量”,只是单位不同。 设置注释文本的坐标系属性,默认与xycoords属性值相同,也可设为不同的值。
arrowprops 字典类型 设置箭头的样式。如果该属性非空,则会在注释文本和被注释点之间画一个箭头。
annotation_clip 布尔值,可选参数 设为True时,只有被注释点在子图区内时才绘制注释;设为False时,无论被注释点在哪里都绘制注释。仅当xycoords为‘data’时,默认值空,相当于True。

xycoordstextcoords的可选参数值如下表所示:

属性值 含义
‘figure points’ 以绘图区左下角为参考,单位是点数
‘figure pixels’ 以绘图区左下角为参考,单位是像素数
‘figure fraction’ 以绘图区左下角为参考,单位是百分比
‘axes points’ 以子绘图区左下角为参考,单位是点数(一个figure可以有多个axex,默认为1个)
‘axes pixels’ 以子绘图区左下角为参考,单位是像素数
‘axes fraction’ 以子绘图区左下角为参考,单位是百分比
‘data’ 以被注释的坐标点xy为参考 (默认值)
‘polar’ 不使用本地数据坐标系,使用极坐标系

注意:arrowprops参数中如果不设置'arrowstyle' 关键字,则允许包含以下关键字:

关键字 说明
width 箭头的宽度(单位是点)
headwidth 箭头头部的宽度(点)
headlength 箭头头部的长度(点)
shrink 箭头两端收缩的百分比(占总长)
? 任何 matplotlib.patches.FancyArrowPatch中的关键字

FancyArrowPatch的关键字包括:

Key Description
arrowstyle 箭头的样式
connectionstyle 连接线的样式
relpos 箭头起始点相对注释文本的位置,默认为 (0.5, 0.5),即文本的中心,(0,0)表示左下角,(1,1)表示右上角
patchA 箭头起点处的图形(matplotlib.patches对象),默认是注释文字框
patchB 箭头终点处的图形(matplotlib.patches对象),默认为空
shrinkA 箭头起点的缩进点数,默认为2
shrinkB 箭头终点的缩进点数,默认为2
mutation_scale default is text size (in points)
mutation_aspect default is 1.

如果设置了arrowstyle关键字,以上关键字就不能使用。允许的值有:

箭头的样式 属性
'-' None
'->' head_length=0.4,head_width=0.2
'-[' widthB=1.0,lengthB=0.2,angleB=None
'|-|' widthA=1.0,widthB=1.0
'-|>' head_length=0.4,head_width=0.2
'<-' head_length=0.4,head_width=0.2
'<->' head_length=0.4,head_width=0.2
'<|-' head_length=0.4,head_width=0.2
'<|-|>' head_length=0.4,head_width=0.2
'fancy' head_length=0.4,head_width=0.4,tail_width=0.4
'simple' head_length=0.5,head_width=0.5,tail_width=0.2
'wedge' tail_width=0.3,shrink_factor=0.5

上述箭头形状如下图所示:
在这里插入图片描述

例如:在余弦图中添加注释

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
x = np.arange(0.0, 5.0, 0.01)
y = np.cos(2*np.pi*x)
line, = ax.plot(x,y,lw=2)
# 注释一
ax.annotate('local max', # 文本内容
            xy=(2, 1), # 箭头指向位置
            xytext=(3, 1.5), # ⽂本位置
            arrowprops=dict(facecolor='black', shrink=0.05)) # 箭头
# 注释二
ax.annotate('local min',
            xy = (2.5,-1),
            xytext = (4,-1.8),
            arrowprops = dict(facecolor = 'black',
                              width = 2, # 箭头宽度
                              headwidth = 10,# 箭头头部宽度
                              headlength = 10, # 箭头头部⻓度
                              shrink = 0.1)) # 箭头两端收缩的百分⽐(占总⻓)
# 注释三
ax.annotate('median',
            xy = (2.25,0),
            xytext = (0,-1.6),
            arrowprops = dict(arrowstyle = '-|>',
                              connectionstyle='arc3,rad=0.5',  # 箭头弯曲
                             ),
            fontsize = 20)
ax.set_ylim(-2, 2)
plt.show()

在这里插入图片描述

两个点之间的连接路径的创建由connectionstyle键控制,并且可用以下样式。

名称 属性
angle angleA=90,angleB=0,rad=0.0
angle3 angleA=90,angleB=0
arc angleA=0,angleB=0,armA=None,armB=None,rad=0.0
arc3 rad=0.0
bar armA=0.0,armB=0.0,fraction=0.3,angle=None

注意,angle3arc3中的3意味着所得到的路径是二次样条段(三个控制点)。 如下面将讨论的,当连接路径是二次样条时,可以使用一些箭头样式选项。每个连接样式的行为在下面的示例中进行演示。
在这里插入图片描述

例如:

import numpy as np
import matplotlib.pyplot as plt
 
# 以步长0.005绘制一个曲线
x = np.arange(0, 10, 0.005)
y = np.exp(-x/2.) * np.sin(2*np.pi*x)
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_xlim(0, 10)
ax.set_ylim(-1, 1)

# 设置被注释点的数据轴坐标和所在的像素
xdata, ydata = 5, 0
xdisplay, ydisplay = ax.transData.transform_point((xdata, ydata))

# 设置注释文本的样式和箭头的样式
bbox = dict(boxstyle="round", fc="0.8")
arrowprops = dict(
    arrowstyle = "->",
    connectionstyle = "angle,angleA=0,angleB=90,rad=10")

# 设置偏移量
offset = 72
# xycoords默认为'data'数据轴坐标,对坐标点(5,0)添加注释
# 注释文本参考被注释点设置偏移量,向左2*72points,向上72points
ax.annotate('data = (%.1f, %.1f)'%(xdata, ydata),
            (xdata, ydata), xytext=(-2*offset, offset), textcoords='offset points',
            bbox=bbox, arrowprops=arrowprops)

# xycoords以绘图区左下角为参考,单位为像素
# 注释文本参考被注释点设置偏移量,向右0.5*72points,向下72points
disp = ax.annotate('display = (%.1f, %.1f)'%(xdisplay, ydisplay),
            (xdisplay, ydisplay), xytext=(0.5*offset, -offset),
            xycoords='figure pixels',
            textcoords='offset points',
            bbox=bbox, arrowprops=arrowprops)

plt.show()

在这里插入图片描述

在下面例子中,我们在极坐标系绘图,并在极坐标系设置被注释点,以绘图区的百分比为参数放置注释文本。

import numpy as np
import matplotlib.pyplot as plt
 
# 绘制一个极地坐标,再以0.001为步长,画一条螺旋曲线
fig = plt.figure()
ax = fig.add_subplot(111, polar=True)
r = np.arange(0,1,0.001)
theta = 2 * 2*np.pi * r
line, = ax.plot(theta, r, color='#ee8d18', lw=3)
 
# 对索引为800处画一个圆点,并做注释
ind = 800
thisr, thistheta = r[ind], theta[ind]
ax.plot([thistheta], [thisr], 'o')
ax.annotate('a polar annotation',
            xy=(thistheta, thisr),  # 被注释点遵循极坐标系,坐标为角度和半径
            xytext=(0.05, 0.05),    # 注释文本放在绘图区的0.05百分比处
            textcoords='figure fraction',
            arrowprops=dict(facecolor='black', shrink=0.05),# 箭头线为黑色,两端缩进5%
            horizontalalignment='left',# 注释文本的左端和低端对齐到指定位置
            verticalalignment='bottom',
            )
plt.show()

在这里插入图片描述

(三)图像层

图像层指Axes内通过plot折线图、scatter散点图、hist柱状图、contour轮廓图、bar柱状图、barbs、pie饼图等函数根据数据绘制出的图像。
在这里插入图片描述

由此我们可以看出

  • Canvas位于最底层,用户一般接触不到
  • Figure建立在Canvas之上
  • Axes建立在Figure之上
  • 坐标轴、图例等辅助信息层以及图像层都是建立在Axes之上

1. Pyplot 模块绘图类型总结

Matplotlib 可以绘制很多图表,常见的线形图、柱状图、直方图与密度图、饼图等都可以绘制,还有特殊的图表,例如:散点图、面积图、箱型图、填充图和极轴图等都可以调用特定函数完成。下表对这些图表的绘制方式进行总结。

图表名称 函数 示例
线形图 plt.plot() x = np.arange(0, 3*np.pi, 0.1)
y_sin = np.sin(x)
plt.plot(x, y_sin, “–”)
柱状图 plt.bar()
plt.barh()
x = [1,2,3,4,5]
y = [6,10,4,5,1]
plt.barh(x,width=y,height=0.5,align=“center”,color=“b”,tick_label=[“A”,“B”,“C”,“D”,“E”],alpha=0.6)
直方图 plt.hist() a = [131, 98, 125, 131, 124, 139, 131, 117, 128, 108]
d = 3
num_bins = (max(a) - min(a))
plt.hist(a, num_bins)
饼图 plt.pie() x = [32,29,15,8,7,9]
department = [“市场部”,“人事部”,“企划部”,“财务部”,“行政部”,“研发部”]
color_ls = [‘r’,‘c’,‘g’,‘b’,‘m’,‘y’]
dist = [0,0,0.2,0,0,0]
plt.axes(aspect=1)
plt.pie(x,labels=department,autopct="%.1f%%",colors=color_ls,explode=dist,shadow=True)
面积图 plt.stackplot()
df.plot.area()
days = [1,2,3,4,5]
sleeping =[7,8,6,11,7]
eating = [2,3,4,3,2]
working =[7,8,7,2,2]
playing = [8,5,7,8,13]
plt.stackplot(days,sleeping,eating,working,playing, colors=[‘r’,‘g’,‘k’,‘y’], baseline=‘sym’)
散点图 plt.scatter()
pd.plotting.scatter_matrix()
x_coords = [0.13, 0.22, 0.39, 0.59, 0.68, 0.74,0.93]
y_coords = [0.75, 0.34, 0.44, 0.52, 0.80, 0.25,0.55]
plt.scatter(x_coords, y_coords, marker = ‘s’, s = 50)
箱型图 plt.boxplot() x = np.linspace(0.05, 10, 50)
y = np.sin(x)
a = np.random.randn(100)
b = np.random.randn(100)
plt.boxplot([a, b, x, y], notch = True, sym = ‘b+’, vert = 0, widths=0.3)
填充图 ax.fill()
ax.fill_between()
x = np.linspace(0, 5 * np.pi, 1000)
y1 = np.sin(x)
y2 = np.sin(2 * x)
axes[1].fill_between(x, y1, y2, color =‘b’,alpha=0.5,label=‘area’)

2. matplotlib.pyplot与axes的关系

首先我们需要明白的是plt(pyplot的缩写)只是一个接口,而不是对象。 plt这个接口的意义在于:1)通过该接口直接画图;2)通过接口实例化别的类型的对象(如figure类型 axes类型等)。plt模块中有很多方法和函数可以用于绘图和设置辅助显示层的图表要素。通过实例化figureaxes对象绘图时,我们首先需要利用plt接口生成figure对象和axes对象,然后对axes对象调用方法来实现画图和设置。这两种方式之间最大的区别就是:前者没有一个显性的对象,它只是作用在一个最新操作的图表axes中,而后者是通过指定实例对象名称作用在具体的目标图表上。上述两种绘图方法在操作时调用的函数有所不同:

plt模块中的函数 axes对象中的函数 函数作用
plt.bar() ax.bar() 绘制垂直条形图
plt.barh() ax.barh() 绘制水平条形图
plt.boxplot() ax.boxplot() 绘制箱线图
plt.hist() ax.hist() 绘制频率直方图
plt.plot() ax.plot() 绘制折线图
plt.title() ax.set_title() 设置图表标题
plt.grid() 设置图表网格
plt.xlabel();plt.ylabel ax.set_xlabel(); ax.set_ylabel 设置x;y轴标题
plt.xticks();plt.yticks() ax.set_xticks(); ax.set_yticks() 设置x;y轴刻度
plt.xlim();plt.ylim() ax.set_xlim(); ax.set_ylim() 设置x;y轴范围
plt.annotate() ax.annotate() 设置标注

注意:在axes对象中绘图时,ax.bar()ax是实例对象名称,在绘制图表或设置图表要素时需要改成实际的实例对象名称。

  1. 通过接口直接画图(这时候我们把这个接口看成一个黑盒,根本不要去管其中有些什么对象类型)
  2. 通过接口实例化别的类型的对象(如figure类型 axes类型等)

二. 设置Plot的风格和样式

(一)设置颜色

配色是一个复杂的话题,涉及到数据理解、色彩学、美学等,但我们应该先从最基本的,如何为图表元素指定颜色开始。在Matplotlib中,要为图表元素,如线条、文字、坐标轴等指定颜色,有两种方法:

  • 直接使用matplotlib能够识别的颜色定义格式,如某个颜色集中的颜色名称或名称的简写、十六进制的颜色定义字符串、RGB值元组等。 这是基础。
  • 使用colormap,将数据映射为颜色模型。

1. 格式化颜色设置

Matplotlib可以识别 8 种格式定义的颜色,可以直接将这些格式的颜色定义赋值给绘图元素的color参数。颜色设置的具体方式如下:

(1)常用颜色的字母表示及缩写

在这里插入图片描述

(2)T10调色盘

Tableau是一个数据分析软件,它有一个10分类的调色板(‘T10’ categorical palette)用于为图表配色(默认色环):insensitive):{'tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan'}

Matplotlib支持该调色板的颜色,不区分大小写。matplotlib在colors模块的TABLEAU_COLORS字典中保存了该调色板的颜色名称和对应的定义颜色的十六进制值。
在这里插入图片描述

(3)CN式写法

CN式写法以字母C为前缀,后面加从0开始的数字索引,其索引的对象为rcParams[“axes.prop_cycle”]指定的调色盘,所以默认情况下,colors=['C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9']的写法和T10调色盘的输出完全一致。

当我们修改调色盘时,CN式写法对应的颜色也会发生变化,代码如下:

import matplotlib as mpl
from cycler import cycler

mpl.rcParams['axes.prop_cycle'] = cycler(color=['r', 'g', 'b', 'y', 'c', 'm', 'k'])
plt.pie(x=[1,1,1,1,1,1,1], colors=['C0','C1', 'C2', 'C3', 'C4', 'C5', 'C6'])
(4)xkcd颜色名称

xkcd调色盘是通过对上万名参与者进行调查而总结出的954种最常用的颜色名称和对应的十六进制值,官方网站如下:https://xkcd.com/color/rgb/。matplotlib在colors模块的XKCD_COLORS字典中保存了该颜色集的全部名称和对应的定义颜色的十六进制值。
在这里插入图片描述

在matplotlib中,通过xkcd:对应的颜色名称进行使用,而且是不区分大小写的,例如:

plt.pie(x=[1,2,3,4], colors=['xkcd:blue','xkcd:orange','xkcd:green','xkcd:red'])
(5)X11/CSS4颜色名称

X11系列颜色通过名称来对应具体的颜色编码,后来的CSS颜色代码也是在其基础上发展而来。在matplotlib中,以字典的形式保存了该颜色集的定义,颜色名称是字典的keys, 定义颜色的十六进制值是对应的values。调用matplotlib.colors模块中的 CSS4_COLORS字典可以输出该颜色集,共有148种颜色。部分颜色示意如下:
在这里插入图片描述

(6)十六进制颜色代码

十六进制的颜色代码可以精确的指定颜色,在matplotlib中当然也支持,用法如下:

plt.pie(x=[1,2,3,4], colors=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728'])

在这里提供一个十六进制颜色查找的网站:https://encycolorpedia.cn/。

当颜色的十六进制代码中每相邻两个字符相同时就可以将其简写,例如,“# abc“ 相当于 “# aabbcc“,”#abcd” 相当于 “#aabbccdd”。

(7)RGB/RGBA元组

所有的颜色都是有RGB三原色构成,在matplotlib中,可以通过一个[0, 1]区间的浮点数元组来表示red, green, blue三原色的比例,以及一个可选的alpha值来表示透明度,取值范围都是0到1,用法如下:

plt.pie(x=[1,2,3,4], colors=[(0.1, 0.2, 0.5),(0.1, 0.3, 0.5),(0.1, 0.4, 0.5),(0.1, 0.5, 0.5)])
(8)灰度颜色

在matplotlib中,通过0到1之间的浮点数来对应灰度梯度,在使用时,为了有效区分,需要通过引号将其装换为字符。具体用法如下:

plt.pie(x=[1,2,3,4], colors=['0','0.25', '0.5', '0.75'])

2. 颜色条设置

有时我们希望图表元素的颜色与数据集中某个变量的值相关,颜色随着该变量值的变化而变化,以反映数据变化趋势、数据的聚集、分析者对数据的理解等信息,这时,我们就要用到 matplotlib 的颜色映射(colormap)功能,即将数据映射到颜色。

要实现数据到颜色的映射需要做两件事:

  • 变量值的变化范围很大,matplotlib用 [0, 1] 区间的浮点数表示颜色RGB值,首先需要将不同的变量值映射到[0, 1]区间;
  • 将映射[0, 1]区间的变量值映射到颜色。

matplotlib.colors 模块是实现 colormap 配色功能的核心模块。该模块的 Normalize() 类及其子类完成第1个任务;该模块的 colormap 类及其子类完成第2个任务。将上述两个类的实例,(即:定义变量数据映射到[0, 1]区间的规则和[0, 1]映射到颜色的规则)作为参数传递给绘图函数,即可实现颜色反映变量数据属性的目的。

matplotlib提供了三个模块用于对图表的颜色进行操控:matplotlib.cm、matplotlib.colorbar、matplotlib.colors。在matplotlib中,有三种给图表配色的方法:

  • 直观的指定颜色,如,在对象的参数中指定,color=‘red’;
  • 使用colormap,将数据映射为颜色模型。注意,需要支持 cmap 参数的图表类型;
  • 通过y值,使用蒙版数组按y值绘制具有不同颜色的线。

matplotlib内置了7类colormap,用于不同的场景:

  1. Perceptually Uniform Sequential
  2. Sequential
  3. Sequential2
  4. Diverging
  5. Cyclic
  6. Qualitative
  7. Miscellaneous

上述7类colormap场景的参考网址:https://matplotlib.org/stable/gallery/color/colormap_reference.html

import numpy as np
import matplotlib.pyplot as plt


cmaps = [('Perceptually Uniform Sequential', [
            'viridis', 'plasma', 'inferno', 'magma', 'cividis']),
         ('Sequential', [
            'Greys', 'Purples', 'Blues', 'Greens', 'Oranges', 'Reds',
            'YlOrBr', 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu',
            'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', 'YlGn']),
         ('Sequential (2)', [
            'binary', 'gist_yarg', 'gist_gray', 'gray', 'bone', 'pink',
            'spring', 'summer', 'autumn', 'winter', 'cool', 'Wistia',
            'hot', 'afmhot', 'gist_heat', 'copper']),
         ('Diverging', [
            'PiYG', 'PRGn', 'BrBG', 'PuOr', 'RdGy', 'RdBu',
            'RdYlBu', 'RdYlGn', 'Spectral', 'coolwarm', 'bwr', 'seismic']),
         ('Cyclic', ['twilight', 'twilight_shifted', 'hsv']),
         ('Qualitative', [
            'Pastel1', 'Pastel2', 'Paired', 'Accent',
            'Dark2', 'Set1', 'Set2', 'Set3',
            'tab10', 'tab20', 'tab20b', 'tab20c']),
         ('Miscellaneous', [
            'flag', 'prism', 'ocean', 'gist_earth', 'terrain', 'gist_stern',
            'gnuplot', 'gnuplot2', 'CMRmap', 'cubehelix', 'brg',
            'gist_rainbow', 'rainbow', 'jet', 'nipy_spectral', 'gist_ncar'])]

gradient = np.linspace(0, 1, 256)
gradient = np.vstack((gradient, gradient))

def plot_color_gradients(cmap_category, cmap_list):
    # Create figure and adjust figure height to number of colormaps
    nrows = len(cmap_list)
    figh = 0.35 + 0.15 + (nrows + (nrows-1)*0.1)*0.22
    fig, axes = plt.subplots(nrows=nrows, figsize=(6.4, figh))
    fig.subplots_adjust(top=1-.35/figh, bottom=.15/figh, left=0.2, right=0.99)

    axes[0].set_title(cmap_category + ' colormaps', fontsize=14)

    for ax, name in zip(axes, cmap_list):
        ax.imshow(gradient, aspect='auto', cmap=plt.get_cmap(name))
        ax.text(-.01, .5, name, va='center', ha='right', fontsize=10,
                transform=ax.transAxes)

    # Turn off *all* ticks & spines, not just the ones with colormaps.
    for ax in axes:
        ax.set_axis_off()

for cmap_category, cmap_list in cmaps:
    plot_color_gradients(cmap_category, cmap_list)

plt.show()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(二)设置线型

Matplotlib中可以设置的线型样式如下表所示:

线型样式 代表的线型
‘-’ solid line style(实线样式)
‘–’ dashed line style(虚线样式)
‘-.’ dash-dot line style(虚点线样式)
‘:’ dotted line style(冒号样式)

(三)设置点型(标记)

Matplotlib中可以设置的点标记样式如下表所示:

'.'       point marker
','       pixel marker
'o'       circle marker
'v'       triangle_down marker
'^'       triangle_up marker
'<'       triangle_left marker
'>'       triangle_right marker
'1'       tri_down marker
'2'       tri_up marker
'3'       tri_left marker
'4'       tri_right marker
's'       square marker
'p'       pentagon marker
'*'       star marker
'h'       hexagon1 marker
'H'       hexagon2 marker
'+'       plus marker
'x'       x marker
'D'       diamond marker
'd'       thin_diamond marker
'|'       vline marker
'_'       hline marker

在这里插入图片描述

三. 设置图表其他内容

(一)保存图表

Matplotlib中保存图片很容易,只需调用plt.savefig()函数即可完成保存。其调用格式如下:

matplotlib.pyplot.savefig(fname, dpi=None, facecolor=’w’, edgecolor=’w’, orientation=’portrait’, papertype=None, format=None, transparent=False, bbox_inches=None, pad_inches=0.1, frameon=None, metadata=None)

参数说明如下:

参数 属性 描述
fname 如果格式已经设置,这将决定输出的格式并将文件按fname来保存。如果格式没有设置,在fname有扩展名的情况下推断按此保存,没有扩展名将按照默认格式存储为“png”格式,并将适当的扩展名添加在fname后面。
dpi 分辨率 每英寸的点数
facecolor 颜色或“auto”,默认值:“auto” 设置图形表面颜色,如果是“auto”,使用当前图形的表面颜色
edgecolor 颜色或“auto”,默认值:“auto” 设置图形边缘颜色,如果是“auto”,使用当前图形的边缘颜色
orientation 可选值为{‘landscape,’ ‘portrait’}
format 设置文件格式,比如“png”,“pdf”,“svg”等,未设置的行为将被记录在fname中
papertype 可以设置为“a0到a10”, “executive,” “b0 to b10”, “letter,” “legal,” “ledger.”
bbox_inches 只有图形给定部分会被保存
pad_inches 设置所保存图形周围的填充量
transparent 用于将图片背景设置为透明。图形也会是透明,除非通过关键字参数指定了表面颜色和/或边缘颜色

例如:

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

mpl.rcParams['font.sans-serif'] = ['SimSun']
mpl.rcParams['font.serif'] = ['SimSun']
mpl.rcParams['axes.unicode_minus'] = False
x = np.arange(5)
a = np.random.random(5)
b = np.random.random(5)
c = np.random.random(5)
total_width, n = 0.8, 3
width = total_width / n
x = x - (total_width - width) / 2
plt.bar(x, a,  width=width, label='A')
plt.bar(x + width, b, width=width, label='B')
plt.bar(x + 2 * width, c, width=width, label='C')
plt.legend()
ax = plt.gca()
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_linewidth('2.0')
ax.spines['left'].set_linestyle('--')
ax.spines['right'].set_visible(False)
plt.savefig('D:\\DataAnalysis\\Data_Analysis_Base\\matplotlib_tutorials\\Base_factor\\Set_Spines.png')
plt.show()

如此,上述代码绘制的图片就可以保存在指定的文件夹之下。

(二)显示中文字符

在matplotlib绘图过程中,中文的标题或者轴标中如果含有中文,会出现不能正常显示的问题。因此要对图表中的中文内容显示进行设置。

1.全局设置

在图表绘制中如果需要在全局范围内设置显示中文字符,就需要利用rcParams变量来设置。如下代码:

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
 
x = np.linspace(-10,10,200)
y = x
plt.plot(x,y)
 
# 设置matplotlib正常显示中文和负号
matplotlib.rcParams['font.sans-serif']=['SimHei']
matplotlib.rcParams['axes.unicode_minus']=False
 
plt.xlabel("横轴/单位")
plt.ylabel("纵轴/单位")
plt.title("标题")
plt.show()

在这里插入图片描述

该方法具有全局作用范围,会将所有字体设置为黑体。而如果不加入第11行代码,会导致负号无法显示。

2.局部设置

如果希望对图表中不同部分采用个性化的设置方案,可以使用FontProperties设置方法。例如:

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
 
x = np.linspace(-10,10,200)
y = x
plt.plot(x,y)
 
font1 = FontProperties(fname=r"c:\windows\fonts\simsun.ttc")
font2 = FontProperties(fname=r"c:\windows\fonts\STHUPO.TTF")
font3 = FontProperties(fname=r"c:\windows\fonts\STCAIYUN.TTF")
 
plt.xlabel("横轴/单位",fontproperties=font1)
plt.ylabel("纵轴/单位",fontproperties=font2)
plt.title("标题",fontproperties=font3)
plt.show()

在这里插入图片描述

这里的字体来自于系统,因此字体形式更加丰富,但是需要找到字体存放的路径,Windows下的默认路径为:C:\Windows\Fonts。由于Windows的文件系统并不区分大小写,因此这里对大小写问题不需要过多留意。

上一种方法虽然能够实现个性化的配置,并且不会影响全局字体环境,但配置步骤相对繁琐,这里介绍一种更为简单的方法:

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
 
x = np.linspace(-10,10,200)
y = x
plt.plot(x,y)
 
plt.xlabel("横轴/单位",fontproperties="STLiti")
plt.ylabel("纵轴/单位",fontproperties="STXingkai")
plt.title("标题",fontproperties="STXinwei")
plt.show()

其中,fontproperties后跟字体名称,字体中英文名称对应关系见下表:

序号 字体 字体名
1 黑体 SimHei
2 楷体 KaiTi
3 隶书 LiSu
4 幼圆 YouYuan
5 华文细黑 STXihei
6 华文楷体 STKaiti
7 华文宋体 STSong
8 华文中宋 STZhongsong
9 华文仿宋 STFangsong
10 方正舒体 FZShuTi
11 方正姚体 FZYaoti
12 华文彩云 STCaiyun
13 华文琥珀 STHupo
14 华文隶书 STLiti
15 华文行楷 STXingkai
16 华文新魏 STXinwei

(三)默认设置

Pylot使用rc配置文件来自定义图形的各种默认属性,称之为rc配置或rc参数。通过rc参数可以修改默认的属性,包括窗体大小、每英寸的点数、线条宽度、颜色、样式、坐标轴、坐标和网络属性、文本、字体等。

在matplotlib模块载入的时候会调用rc_params,并把得到的配置字典保存到rcParams变量中。既然是配置文件,它也是一个文件,这个文件存在于matplotlib的安装文件夹之下,比如我的在以下文件夹:D:\ProgramData\Anaconda3\Lib\site-packages\matplotlib\mpl-data中,文件名称是 matplotlibrc。我们可以通过文本文件打开这个文件进行查看,可以发现,里面的内容都是“ 键-值 ”的形式,这也就是为什么我们可以通过mpl.rcParams['font.sans-serif'] = ['SimHei']这种形式加以配置了。

1. 查看默认配置信息

查看默认相关配置有以下两种方式:

  • 方式一:直接打开matplotlibrc文件

  • 方式二:

  • print(matplotlib.rc_params())
    # 或者
    print(matplotlib.rcParamsDefault)   
    # 或者
    print(matplotlib.rcParams) 
    

2. 设置相关配置

(1)修改相关配置
  • 修改方式一

    mpl.rcParams['lines.linewidth'] = 2
    mpl.rcParams['lines.color'] = 'r'
    
  • 修改方式二

    mpl.rc('lines', linewidth=4, color='g')
    
(2)恢复默认配置
mpl.rcdefaults()
(3)从已有的文件更新
mpl.cr_file()

3. rc参数的的常用的基本种类

在rcparams参数中常用的基本类型如下:

  • animation开头:动态设置
  • font开头:字体设置
  • axes开头:内框画布
  • figure开头:外框画布
  • boxplot开头:箱线图
  • grid开头:网格标签
  • image开头:图片设置
  • keymap开头:快捷键设置
  • legend开头:图例设置
  • lines开头:线条设置
  • mathtext开头:数学公式字体相关
  • xtick开头:x轴标签
  • ytick开头:y轴标签

rc参数常用设置示例:

序号 属性 说明
字体设置
1 plt.rcParams[’axes.unicode_minus’] = False 字符显示
2 plt.rcParams[’font.sans-serif’] = ‘SimHei’ 设置字体
线条样式:lines
1 plt.rcParams[’lines.linestyle’] = ‘-.’ 线条样式
2 plt.rcParams[’lines.linewidth’] = 3 线条宽度
3 plt.rcParams[’lines.color’] = ‘blue’ 线条颜色
4 plt.rcParams[’lines.marker’] = None 默认标记
5 plt.rcParams[’lines.markersize’] = 6 标记大小
6 plt.rcParams[’lines.markeredgewidth’] = 0.5 标记附近的线宽
x轴、y轴:xtick、ytick
1 plt.rcParams[’xtick.labelsize’] x轴字体大小
2 plt.rcParams[’ytick.labelsize’] y轴字体大小
3 plt.rcParams[’xtick.major.size’] x轴最大刻度
4 plt.rcParams[’ytick.major.size’] y轴最大刻度
figure中的子图:axes
1 plt.rcParams[’axes.titlesize’] 子图的标题大小
2 plt.rcParams[’axes.labelsize’] 子图的标签大小
图像、图片:figure、savefig
1 plt.rcParams[’figure.dpi’] 图像分辨率
2 plt.rcParams[’figure.figsize’] 图像显示大小
3 plt.rcParams[’savefig.dpi’] 图片像素

(四)预设风格Style

使用matplotlib画图的时候,除了我们可以针对每一个样式自己定义以外,我们还可以使用系统定义好的样式快速配置。

style是pyplot的一个子模块,方便进行风格转换,它里面定义了很多预设风格。本质上来说,每一个预设的风格style都是一个style文件,它是以 .mplstyle 为后缀的文件。我们依然可以查看,比如我的电脑在以下文件夹下,有很多的 .mplstyle文件:D:\ProgramData\Anaconda3\Lib\site-packages\matplotlib\mpl-data\stylelib。每一个文件名对应于一种预设风格。我们可以打开一个文件,里面预设的风格属性也是通过“ 键-值 ”对的形式表示的。

1. 设置和使用预设风格

(1)查看预设风格
  • 方式一:直接查看相应的文件夹即可

  • 方式二:

  • print(plt.style.available)  #会打印出所有的预设风格的名称
    
(2)使用预设风格
x=np.linspace(0,2*np.pi)
y=np.sin(x)
plt.style.use('ggplot')                         ##使用 ggplot  的绘图风格
plt.plot(x,y,label='sin',linewidth=5)
plt.legend()
plt.show()

在这里插入图片描述

(3)自定义预设风格

比如我在上面所述的文件夹下自定义一个 myownstyle.mplstyle 文件,里面的内容如下所示:

lines.color: green
lines.linewidth:8
patch.edgecolor: red

text.color: white

axes.facecolor: yellow
axes.edgecolor:black

然后调用如下:

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

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

f=plt.figure()
plt.style.use('self_style')    ##使用自定义的样式文件
plt.plot(x,y,label='sin',linewidth=5)
plt.legend()

plt.show()

运行结果为:
在这里插入图片描述

除此之外,我们还可以使用with代码块。在代码块内部画的图是制定的风格,而在代码块外部画的图却不用这种风格,如下代码所示:

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

x = np.linspace(0, 2 * np.pi)
with plt.style.context('dark_background'):  # 将use换成context
    plt.figure()
    plt.plot(x, np.cos(x), 'r-o', label='cosine')
    plt.legend()
f = plt.figure()
plt.plot(x, np.sin(x), label='sine')
plt.legend()
plt.show()

上述代码先后分别绘制如下两个图表:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_45617055/article/details/114282325