上一次我们在Matplotlib1-学会自己手打图片中介绍了使用matplotlib的基本知识,包括 Pyplot是什么,pyplot接口有哪些,怎么样使用pyplot 函数直接绘图,figure图形对象和 axes轴域对象,pyplot.plot() 方法如何使用, 轴标签和标题怎么设置,图例和网格线怎么设置,坐标轴怎么设置,以及如何绘制子图,以及有哪些绘制子图的方式。今天我们进一步补充如何使用matplotlib绘制出更加完整的图画。
尽管我们已经在Matplotlib1-学会自己手打图片中介绍过如何设置图片的刻度以及刻度标签,并且进行了举例说明。然而我们当时使用的例子是使用固定刻度数量和固定标签数量的案例,如果我们面临着横纵坐标数量很多的情况,我们要如何去自适应的设置刻度以及匹配标签呢?
首先,我们要知道,刻度指的是轴上数据点的标记,Matplotlib 能够自动的在 x 、y 轴上绘制出刻度。这一功能的实现得益于 Matplotlib 内置的刻度定位器和格式化器(两个内建类)。在大多数情况下,这两个内建类完全能够满足我们的绘图需求,但是在某些情况下,刻度标签或刻度也需要满足特定的要求,比如将刻度设置为“英文数字形式”或者“大写阿拉伯数字”,此时就需要对它们重新设置。
我们采用下列案例进行说明如何灵活调整图片的刻度和刻度标签。
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.figure()
plt.plot(x, y)
plt.xlabel('X轴标签') # 设置x轴标签
plt.ylabel('Y轴标签') # 设置y轴标签
plt.show()
我们使用np.linspace()函数生成在[0,10]之间的100个数,并且同步计算出这些数的sin()函数。我们如果不设置X轴和Y周的刻度和刻度标签,那么matplotlib会自动为我们设置好相应的轴标签。生成的图像如下所示:
然而,如果我们希望对X轴进行标签设置,比如,我想让X轴的刻度显示11个数值,并且每个刻度标签都用英文数字标识,同时使得X轴刻度标签向左旋转30度。那么我们则需要使用xticks()对X轴进行动态调整。我们可以使用np.arrange()函数选定好X轴的范围,然后选好每个衡坐标的间隔,就可以重塑X轴。然后我们根据自定义好的刻度标签进行刻度标签修改。这里需要注意,刻度数量和标签数量必须得对齐,不然会报错。大家可以参考下面这个示例。
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
print(x)
y = np.sin(x)
plt.figure()
plt.plot(x, y)
# 设置x轴刻度,从0到10,间隔为1,并使用英文数字标签
plt.xticks(np.arange(0, 11, 1), ['Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'six', 'seven', 'Eight', 'Nine', 'Ten'])
# 设置刻度标签旋转30度
plt.tick_params(axis='x', labelrotation=30)
# plt.yticks(np.arange(-1, 1, 0.2)) # 设置y轴刻度,从-1到1,间隔为0.2
plt.xlabel('X label') # 设置x轴标签
plt.ylabel('Y label') # 设置y轴标签
plt.show()
同理,我们也可以设置Y轴,这里就不做赘述了。
那可能有的小伙伴就会问了,如果我的横坐标很重要,我都想显示出来,只是我的数据量太大,如果全部显示则会出现数值重叠,那么我应该怎么按比例挑选出一些值进行显示呢?在上述例子中,其实横坐标有100个,但是matplotlib帮我们自动隐藏了很多横坐标,同时也没有将横坐标实际的值显示出来。那么我们假设依然是显示10个刻度,但是我们希望是把刻度的真实值显示出来,那么我们应该怎样做呢?其实很简单,就是修改刻度标签,请看代码。
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.figure()
plt.plot(x, y)
# 设置x轴刻度,从0到10,间隔为1,并使用英文数字标签
xticks_label_int = x[::10]
xticks_label_text = [str(i) for i in xticks_label_int]
plt.xticks(np.arange(0, 10, 1), xticks_label_text)
# 设置刻度标签旋转30度
plt.tick_params(axis='x', labelrotation=30)
# plt.yticks(np.arange(-1, 1, 0.2)) # 设置y轴刻度,从-1到1,间隔为0.2
plt.xlabel('X label') # 设置x轴标签
plt.ylabel('Y label') # 设置y轴标签
plt.show()
在上述代码中,我们通过np.arrange()函数设置好了X轴的数值范围个刻度打点的具体位置,xticks_label_text则是在X轴的打点位置填上需要表示的数值或者标识,是不是很简单。上述代码的生成图像如下:
坐标轴轴线就横纵坐标的那根连接刻度的线,也就是绘图区域的边界,在绘图区域(axes 对象)的顶部、底部、左侧和右侧都有一个边界线(轴)。通过指定轴的颜色和宽度,从而对进行显示格式设置,比如将所有轴的颜色设置为 None,那么它们都会成为隐藏状态,或者也可以给轴添加相应的颜色。尽管给坐标轴上色是个比较少用的功能,因为需要使用的场景比较少,但是matplotlib确实提供了给坐标轴上色的功能,还可以调整坐标轴线条粗细和控制是否显示轴线。
以下示例为左侧轴、底部轴分别设置了红色、蓝色,如下所示:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
y = np.sin(x)
fig = plt.figure()
ax = fig.add_axes([0.12,0.2,0.85,0.75])
ax.plot(x, y)
# 设置x轴刻度,从0到10,间隔为1,并使用英文数字标签
xticks_label_int = x[::10]
xticks_label_text = [str(i) for i in xticks_label_int]
ax.set_xticks(np.arange(0, 10, 1), xticks_label_text, rotation = 30) # 设置刻度标签旋转30度
# plt.yticks(np.arange(-1, 1, 0.2)) # 设置y轴刻度,从-1到1,间隔为0.2
ax.set_xlabel('X label') # 设置x轴标签
ax.set_ylabel('Y label') # 设置y轴标签
#为左侧轴,底部轴添加颜色
ax.spines['bottom'].set_color('blue')
ax.spines['left'].set_color('red')
ax.spines['left'].set_linewidth(2)
# 隐藏右侧、顶部边框
# ax.spines['top'].set_visible(False)
# ax.spines['right'].set_visible(False)
plt.show()
在Matplotlib中,spines
是一个用于控制坐标轴边框的属性。它是一个字典,其中键是轴的名称(如"top", "bottom", "left", "right"),值是对应的轴对象。通过修改spines
字典中的属性,可以控制坐标轴边框的显示、隐藏、位置和外观等。spines()
方法用于显示或隐藏坐标轴的边框。它接受一个布尔值参数,如果为True,则显示边框;如果为False,则隐藏边框。例如:
ax.spines['top'].set_visible(False) # 隐藏顶部边框
ax.spines['right'].set_visible(False) # 隐藏右侧边框
除了set_visible()
方法外,spines()
方法还提供了其他一些参数,用于进一步定制坐标轴边框的外观和位置:
set_color()
: 设置边框的颜色。set_linewidth()
: 设置边框线宽。set_linestyle()
: 设置边框线型,如实线、虚线、点划线等。set_marker()
: 设置边框标记样式。set_capstyle()
: 设置边框端点的样式。set_offset()
: 设置边框相对于坐标轴位置的偏移量。可以传入一个表示位置的元组(x, y),其中x和y是相对于坐标轴的比例因子。set_position()
: 设置边框的位置。可以传入一个表示位置的元组(left, width),其中left是左侧位置的比例因子,width是宽度的比例因子。例如,('data', 0.1)
将左侧位置移动到数据位置的0.1处。这些参数可以根据需要进行组合,以定制坐标轴边框的外观和位置,使其更好地适应数据和图表的整体风格。
当然,在上面的代码中,你可能需要根据需要调整Axes的区域以适应画布。如果你不喜欢手动调整,你可以使用figure.tight_layout()进行自动的布局调整。
figure.tight_layout()是一个常用于自动调整子图之间的空间,以便它们在图中的布局更加紧凑。当你创建多个子图(subplots)时,有时可能会出现子图之间的间隔过大或过小,或者子图与图边框之间的间隔过大或过小的情况。在这种情况下,使用 tight_layout()
可以自动调整这些间隔,使得子图在视觉上更加整齐和紧凑。
import matplotlib.pyplot as plt
import numpy as np
# 创建数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
# 创建两个子图
fig, (ax1, ax2) = plt.subplots(2, 1)
ax1.plot(x, y1)
ax2.plot(x, y2)
# 使用 tight_layout() 调整布局
fig.tight_layout()
plt.show()
双轴也是matplotlib的一种基本使用。在一些应用场景中,有时需要绘制两个 x 轴或两个 y 轴,这样可以更直观地显现图像,从而获取更有效的数据。Matplotlib 提供的 twinx() 和 twiny() 函数,除了可以实现绘制双轴的功能外,还可以使用不同的单位来绘制曲线,比如一个轴绘制对函数,另外一个轴绘制指数函数。我们以 twinx()为例来进行说明。
twinx()是 Matplotlib 中的一个函数,用于创建一个与现有轴共享x轴,但y轴不同的第二个轴。这样,你可以在同一个图上展示两种不同类型的数据,但y轴的范围和刻度可以是不同的。使用 twinx()创建的第二个y轴可以独立地控制其y轴的范围和刻度。下面是一个简单的例子:
import numpy as np
import matplotlib.pyplot as plt
# 创建数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = [(i**2) for i in x]
# 创建第一个子图
fig, ax1 = plt.subplots()
ax1.plot(x, y1,'r') # 使用红色绘制y1
ax1.set_xlabel('X Axis 1') # x轴标签
ax1.set_ylabel('Y Axis 1', color='r') # y轴标签,颜色设置为红色
# 使用 twinx() 创建第二个子图,并设置其y轴标签和颜色
ax2 = ax1.twinx()
ax2.plot(x, y2, 'b') # 使用蓝色绘制y2
ax2.set_ylabel('Y Axis 2', color='b') # y轴标签,颜色设置为蓝色
plt.show()
在这个例子中,我们创建了一个包含两个子图的图形。第一个子图显示了sin(x)的值,并且其y轴标签为红色。第二个子图显示了x**2的值,并且其y轴标签为蓝色。两个子图共享同一个x轴,但它们的y轴范围和刻度是独立的。在双轴图上,我们之前学过的所有针对坐标轴的操作都能单独针对每个图进行。
文本绘制就是在图上添加上相关文字,这点在使用matplotlib画图时非常常见,特别是一些用于科学论文的复杂图片,经常需要再图片中特定位置进行特殊标记,其中就包括文字标记。
pyplot.text()是 Matplotlib 中的一个函数,用于在图表上添加文本。它可以用于在指定的位置添加文本字符串,并提供了一些选项来控制文本的外观和格式。函数的基本语法如下:
pyplot.text(x, y, s, fontsize=None, color=None, alpha=None, rotation=None, horizontalalignment='center', verticalalignment='center', multialignment=None, linewidth=None, linestyle=None, marker=None, markersize=None,*, data=None)
'''
x 和 y:文本字符串的左下角坐标。
s:要添加的文本字符串。
fontsize:字体大小。
color:文本颜色。
alpha:透明度。
rotation:文本旋转角度。
horizontalalignment:水平对齐方式,可选值为 'center'、'left' 或 'right'。
verticalalignment:垂直对齐方式,可选值为 'center'、'top'、'bottom' 或 'baseline'。
multialignment:多行文本的对齐方式,只在文本字符串包含换行符时有效。可选值为 'left'、'center' 或 'right'。
data:用于指定相对坐标的轴数据,例如在极坐标图中使用时需要指定。
ha:水平对齐方式,可选值为 'center'、'right' 或 'left'。
va:垂直对齐方式,可选值为 'center'、'top'、'bottom' 或 'baseline'。
position:文本的位置,可以是 (x, y) 坐标或 'bottom left'、'bottom right'、'top left' 或 'top right' 等位置字符串。
bbox:文本的边框属性,包括 facecolor、edgecolor、linewidth 和 clip_on 参数。
angle:旋转角度,以度为单位。
zorder:绘图顺序,数值越高表示越在上面。
'''
以下是一个简单的示例,演示如何使用 pyplot.text()
函数在图表上添加文本:
import matplotlib.pyplot as plt
import numpy as np
# 创建数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 创建图表
fig, ax = plt.subplots()
ax.plot(x, y)
# 在图表上添加文本
ax.text(5, 0.5, 'sin(x)', fontsize=12, color='red')
# 显示图表
plt.show()
在上述示例中,我们创建了一个简单的正弦曲线图,并使用 ax.text()
方法在 (5, 0.5) 位置添加了红色、字体大小为12的文本字符串 "sin(x)"。
如果你想要在图表上显示多行文本,你可以使用Text
对象的set_text()
方法来设置文本内容,并在需要换行的地方使用\n
。多行文本换行之后默认是使用‘center’进行水平对齐,例如:
import matplotlib.pyplot as plt
import numpy as np
# 创建数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 创建图表
fig, ax = plt.subplots()
ax.plot(x, y)
# 设置文本内容,其中"\n"表示换行符
text = 'Hello\nWorld'
ax.text(5, 0.5, text, fontsize=12, color='red')
plt.show()
# 显示图表
plt.show()
在上述示例中,字符串"Hello\nWorld"中的\n
被转换为LaTeX的换行表示,因此文本将在图表上分为两行显示。
pyplot.text()同时支持打印Latex公式,具体的使用方法是将文本标记符放在一对美元符号$内,这是Latex的经典语法。以下是在示例代码中添加LaTeX公式的示例:
import matplotlib.pyplot as plt
import numpy as np
# 创建数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 创建图表
fig, ax = plt.subplots()
ax.plot(x, y)
# 在图表上添加文本和LaTeX公式
ax.text(5, 0.5, r'$\alpha = \frac{\pi}{2}$', fontsize=12, color='red')
# 显示图表
plt.show()
在上述示例中,我们在图表上添加了一个LaTeX公式 α=π/2,并使用ax.text()
方法将其放置在坐标 (5, 0.5) 处。请注意,我们在字符串前面使用了r
前缀来表示原始字符串,这样可以在字符串中直接使用LaTeX语法。
最后,就是保存图片环节。我看有很多小伙伴学习matplotlib画图已经非常溜了,但是居然不知道怎么样把他变成文件保存在磁盘中,这简直让我有点感到不可思议。matplotlib保存图片的方式很简单就是plot.savefig()。当你在 Matplotlib 中使用 plot.savefig()方法时,你需要提供要保存的文件名和文件格式。例如:
import matplotlib.pyplot as plt
# 创建一个简单的图表
plt.plot([1, 2, 3, 4], [1, 4, 2, 3])
# 保存图表为 PNG 格式的文件
plt.savefig('my_plot.png')
在上面的例子中,我们首先创建了一个简单的图表,然后使用 plot.savefig()方法将其保存为名为 "my_plot.png" 的 PNG 格式文件。除了savefig(),Matplotlib 还提供了其他用于保存图表的函数,如plot.savefig()的别名 plt.savefig()。这些函数通常用于将图表保存为各种文件格式,如 PDF、SVG、JPG 等。
plot.savefig()(或其别名 plt.savefig())方法在 Matplotlib 中用于保存绘制的图形。以下是该方法的一些常用参数:
'my_plot.png'
。None
,这意味着使用当前图像的分辨率。'png'
、'pdf'
、'svg'
等。如果不指定,将根据文件扩展名自动选择格式。True
,则将生成透明的 PNG 图像。'tight'
会尝试裁剪多余的空白区域。True
,则显示图形边框。'lower'
或 'upper'
。默认是 'lower'
。Matplotlib可以直接处理图形数据,plot.image模块提供了加载、缩放和显示图像的功能,该模块只能支持 PNG 格式的图片,如果格式不符,需要对图片的格式进行转换。所以通常情况下,一般不建议直接使用plot.image模块来处理图像数据,采用 Python 图像处理库 Pillow 或者其他库来处理图像会更好。
imread() 方法是plot.image模块的一个函数,用于从图像文件中读取图像数据。imread() 方法返回一个 numpy.ndarray 对象,其形状是 (nrows, ncols, nchannels),表示读取的图像的行数、列数和通道数:
imread() 方法的语法如下:
matplotlib.pyplot.imread(fname, format=None)
参数说明:
fname
:指定了要读取的图像文件的文件名或文件路径,可以是相对路径或绝对路径。format
:参数指定了图像文件的格式,如果不指定,则默认根据文件后缀名来自动识别格式。import matplotlib.pyplot as plt
# 读取图像文件,下载地址:https://p3.itc.cn/q_70/images03/20210316/bb167df5be10464a8cf407329b883f94.png
img = plt.imread('https://p3.itc.cn/q_70/images03/20210316/bb167df5be10464a8cf407329b883f94.png')
# 显示图像
plt.imshow(img)
plt.show()
以上实例中我们首先使用 imread() 方法从远端读取了png图片https://p3.itc.cn/q_70/images03/20210316/bb167df5be10464a8cf407329b883f94.png,并将其存储在 img 变量中。然后我们使用imshow() 方法显示了这张图像。我们在显示图像时没有指定颜色映射,这是因为 imread() 方法已经将图像数据按照正确的颜色映射转换成了 RGB 格式,因此我们可以直接使用默认的颜色映射来显示图像。
imshow() 函数是 Matplotlib 库中的一个函数,用于显示图像,主要用于绘制二维或三维的图像。imshow() 函数常用于绘制二维的灰度图像或彩色图像,也可用于绘制矩阵、热力图、地图等。基本语法格式如下:
imshow(X, cmap=None, norm=None, aspect=None, interpolation=None, alpha=None, vmin=None, vmax=None, origin=None, extent=None, shape=None, filternorm=1, filterrad=4.0, imlim=None, resample=None, url=None, *, data=None, **kwargs)
参数说明:
X
:输入数据。可以是二维数组、三维数组、PIL图像对象、matplotlib路径对象等。cmap
:颜色映射。用于控制图像中不同数值所对应的颜色。可以选择内置的颜色映射,如gray
、hot
、jet
等,也可以自定义颜色映射。norm
:用于控制数值的归一化方式。可以选择Normalize
、LogNorm
等归一化方法。aspect
:控制图像纵横比(aspect ratio)。可以设置为auto
或一个数字。interpolation
:插值方法。用于控制图像的平滑程度和细节程度。可以选择nearest
、bilinear
、bicubic
等插值方法。alpha
:图像透明度。取值范围为0~1。origin
:坐标轴原点的位置。可以设置为upper
或lower
。extent
:控制显示的数据范围。可以设置为[xmin, xmax, ymin, ymax]
。vmin
、vmax
:控制颜色映射的值域范围。filternorm 和 filterrad
:用于图像滤波的对象。可以设置为None
、antigrain
、freetype
等。imlim
: 用于指定图像显示范围。resample
:用于指定图像重采样方式。url
:用于指定图像链接。import numpy as np
import matplotlib.pyplot as plt
# 创建一个2x2的二维数组(图像)
image = np.array([[1, 2], [3, 4]])
# 使用 imshow() 显示图像
plt.imshow(image)
plt.show()
这个例子将显示一个2x2的图像,其中的值从1到4递增。 我们还可以通过更改 numpy 数组来修改图像。例如,下列代码是用来调节图像的明暗程度:
import matplotlib.pyplot as plt
# 读取图像文件,下载地址:https://p3.itc.cn/q_70/images03/20210316/bb167df5be10464a8cf407329b883f94.png
img = plt.imread('https://p3.itc.cn/q_70/images03/20210316/bb167df5be10464a8cf407329b883f94.png')
# 显示图像
plt.figure(figsize=(10,6))
# 调整图片的明暗程度
for i in range(1,5):
plt.subplot(2,2,i)
x = 1 - 0.2*(i-1)
plt.axis('off') #hide coordinate axes
plt.title('x={:.1f}'.format(x))
plt.imshow(img*x)
plt.show()
在上述代码中,我们对图像对象通过乘以不同的系数来调整图像的明暗程度,并显示结果。 首先,使用plt.figure()
创建一个新的图形窗口,并设置其大小为10x6单位。接下来,使用一个循环来调整图像的明暗程度,并在循环中显示每个调整后的图像。在每次迭代中:
* 使用`plt.subplot()`创建一个子图。例如,`plt.subplot(2,2,i)`表示创建一个2x2的子图布局,当前是第i个子图。
* 使用`plt.axis('off')`隐藏坐标轴。
* 使用`plt.title()`设置子图的标题,显示用于调整明暗程度的系数。
* 使用`plt.imshow()`显示调整后的图像。这里,原始图像(`img`)乘以一个系数x来调整其明暗程度。系数x的值从1递减到0.8,这导致图像从原始状态逐渐变暗。
最后,你会看到4个子图,每个子图显示原始图像的不同明暗程度。当然,你也可以裁剪图像:
import matplotlib.pyplot as plt
# 读取图像文件,下载地址:https://p3.itc.cn/q_70/images03/20210316/bb167df5be10464a8cf407329b883f94.png
img = plt.imread('https://p3.itc.cn/q_70/images03/20210316/bb167df5be10464a8cf407329b883f94.png')
# 显示图像
plt.figure(figsize=(10,6))
# 裁剪图像
plt.imshow(img[:300,100:400,:])
plt.axis('off')
plt.show()
如果我们将 RGB 颜色的绿色和蓝色坐标的数组元素设置为 0,我们将得到红色的图像:
import matplotlib.pyplot as plt
# 读取图像文件,下载地址:https://p3.itc.cn/q_70/images03/20210316/bb167df5be10464a8cf407329b883f94.png
img = plt.imread('https://p3.itc.cn/q_70/images03/20210316/bb167df5be10464a8cf407329b883f94.png')
# 显示红色图像
img[:,:,[1,2]] = 0
plt.imshow(img)
plt.axis('off')
plt.show()
imsave() 方法是 Matplotlib 库中用于将图像数据保存到磁盘上的函数。通过 imsave() 方法我们可以轻松将生成的图像保存到我们指定的目录中。imsave() 方法保存图片支持多种图像格式,例如 PNG、JPEG、BMP 等。imsave() 方法的语法如下:
import matplotlib.pyplot as plt
plt.imsave(filename, image, cmap=None, origin=None, dpi=None, metadata=None)
参数解释:
filename
:这是要保存的文件的名称和路径。image
:这是要保存的图像,通常是一个二维数组。cmap
:颜色映射,用于将数据值映射到颜色。origin
:原点设置,可以是 'lower' 或 'upper'。默认为 'lower'。dpi
:每英寸的点数,即分辨率。默认为 None,使用 rcParams['savefig.dpi']
。metadata
:一个字典,包含要保存为图像元数据的键值对。一个简单的例子:
import numpy as np
import matplotlib.pyplot as plt
# 创建一个2x2的二维数组(图像)
image = np.array([[1, 2], [3, 4]])
# 使用 imshow() 显示图像
plt.imshow(image)
plt.show()
# 使用 imsave() 保存图像到文件
plt.imsave('my_image.png', image)
在这个例子中,首先使用 imshow()
显示了一个2x2的图像,然后使用 imsave()
将这个图像保存为名为 "my_image.png" 的文件。
以上就是我所学习到的关于matplotlib库的除了实际绘制特定类型图形的所有基本知识点了。我们掌握了这些基本点,对于具体图形的绘制几乎是可以一通百通了,无非就是使用不同的函数和构造不同的输入数据而已。后面有机会,我将继续分享使用matplotlib进行具体图形的绘制学习心得。目前已经分享了一期matplotlib之手打柱状图,感兴趣的小伙伴也可以去看看。