matplotilb画图
Matplotlib 是支持 Python 语言的开源绘图库,因为其支持丰富的绘图类型、简单的绘图方式以及完善的接口文档,深受 Python 工程师、科研学者、数据工程师等各类人士的喜欢。Matplotlib 拥有着十分活跃的社区以及稳定的版本迭代,当我们使用 Python 进行数据分析并执行可视化时,Matplotlib 无疑是得心应手的工具之一。
接下来很多内容都是在代码中,说明也在代码里面
import matplotlib.pyplot as plt
#pyplot 模块是 Matplotlib 最核心的模块,几乎所有样式的 2D 图形都是经过该模块绘制出来的,这里简称为 plt 是约定俗成的
import matplotlib
matplotlib.use('TkAgg')
#新版本的matplotilb必须要写一个框架
plt.rcParams["font.sans-serif"]=['SimHei']
#让中文可以显示的操作
pyplot的一些常用图像
- 折线图 (Line plot): 用于展示数据随时间或有序类别变化的趋势。
- 散点图 (Scatter plot): 展示两个变量之间的关系,适用于观察数据点的分布。
- 条形图 (Bar chart): 用于比较不同类别的数据。
- 直方图 (Histogram): 显示数据的频率分布。
- 饼图 (Pie chart): 展示数据的比例或占比。
- 箱形图 (Box plot): 用于显示数据的分布情况,包括中位数、四分位数等。
- 热图 (Heatmap): 通过颜色变化显示数据矩阵的大小。
- 极坐标图 (Polar chart): 在极坐标系中显示数据。
- 3D图形: 用于在三维空间中显示数据。
- 子图 (Subplots): 在同一画布上创建多个图表。
plt.plot() 折线图
是 pyplot
模块下面的**直线绘制(折线类)**方法类。代码中,它取出 x
数据集中的内容,将其按大小打印到图中,并以直线连接每个点。
通常,plot()
接受两个参数。一个代表横坐标的数值,另一个代表纵坐标的数值。但是,当你只传入一个参数 y
的时候,它会默认代表纵坐标的值,而横坐标的值会从 0
到 n-1
,n
为 y
数据长度。
y = [1, 2, 3, 2, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]
plt.plot(y)
plt.show()
import numpy as np
# 在 -2PI 和 2PI 之间等间距生成 1000 个值,也就是 X 坐标
X = np.linspace(-2*np.pi, 2*np.pi, 1000)
# 计算 y 坐标
y = np.sin(X)
plt.plot(X, y)
当你学会线型图绘制之后,可能想到改变图形的属性。例如,更改图形的尺寸、添加图例等。Matplotlib 提供的面向对象 API 使用起来非常简单,但是下面不再直接使用 plt.plot
,而是定义一个绘图对象 fig, axes = plt.subplots()
。
# 生成示例数据
x = np.linspace(0, 10, 20)
y = x * x + 2
fig, axes = plt.subplots() #这个subplots可以一次创建画板和画布两个对象很方便
axes.plot(x, y, 'r')
上面的绘图代码中,你可能会对 fig
和 axes
产生疑问。Matplotlib 的 API 设计的非常符合常理,在这里,fig
相当于绘画用的画板,而 axes
则相当于铺在画板上的画布。我们将图像绘制在画布上,于是就有了 plot
,set_xlabel
等操作。
- Figure (画板):
figure
是绘制所有图形的外部容器。可以想象成一个画板或画框,它为图像提供了一个物理空间。在一个程序中可以有多个figure
对象。在fig, axes = plt.subplots()
这行代码中,fig
是指创建的Figure
对象。在 Matplotlib 中,Figure
对象代表整个图形窗口,它是一个容器,可以包含一个或多个Axes
对象(即图表)。每个Axes
对象代表图形窗口中的一个绘图区域,您可以在其中绘制各种图形。 - Axes (画布):
axes
是figure
内的具体图形空间,可以理解为画布。在axes
上,我们可以绘制具体的图形、设置图表标题、坐标轴标签等。一个figure
可以包含多个axes
。
我们再来看看代码就比较直观
# 创建一个 figure(画板)
fig = plt.figure()
# 向 figure 添加一个 axes(画布),这里的 [0.1, 0.1, 0.8, 0.8] 是 axes 在 figure 中的位置和大小 [left, bottom, width, height]
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
#这里的数字都是对于画板相差多少来的
# 在 axes 上绘制图形
ax.plot([1, 2, 3], [3, 2, 1])
# 显示图形
plt.show()
我们不是说了一个画板上可以有多个画布吗?
#fig, axes = plt.subplots(nrows=x, ncols=y) 子图为x 行,y 列
fig, axes = plt.subplots(nrows=1, ncols=2) #这就是一行两列
axes[0][0].plot(x, y, 'r')
axes[0][1].plot(x, y, 'b')
这就是效果图,很直观吧,一个画板上有2*2
下面是关于调整这个多个画板的操作
关于标题和xy轴
# 绘制包含图标题、坐标轴标题以及图例的图形
fig, axes = plt.subplots()
axes.set_xlabel('x label')
axes.set_ylabel('y label')
axes.set_title('title')
axes.plot(x, x**2)
axes.plot(x, x**3)
axes.legend(["y = x**2", "y = x**3"], loc=2)
别的图像
在使用 Matplotlib 绘制不同类型的图表时,基本的设置步骤通常是相似的。关键在于调用相应的绘图函数(如 scatter
, step
, bar
, fill_between
等)来生成特定类型的图像。每种图表类型的函数都有自己的参数和设置,但通常情况下,布局和标题设置的方式是类似的。我们暂且先讲相似的
代码在这里
# 绘制散点图、梯步图、条形图、面积图
import matplotlib.pyplot as plt
import numpy as np
# 示例数据
x = np.linspace(0, 5, 10)
y = x ** 2
# 散点图
plt.figure(figsize=(5, 4))
plt.scatter(x, y, c='blue', marker='o', s=50, alpha=0.5, label='Scatter plot')
plt.title("Scatter Plot Example")
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
plt.legend()
plt.show()
# 梯步图
plt.figure(figsize=(5, 4))
plt.step(x, y, where='mid', lw=2, label='Step plot')
# where='mid'
plt.title("Step Plot Example")
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
plt.legend()
plt.show()
# 条形图
n = np.arange(len(x))
plt.figure(figsize=(5, 4))
plt.bar(n, y, align="center", width=0.5, alpha=0.5, label='Bar plot')
plt.xticks(n, x) # 设置x轴刻度标签为x的值
plt.title("Bar Plot Example")
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
plt.legend()
plt.show()
# 面积图
plt.figure(figsize=(5, 4))
plt.fill_between(x, y, y2=0, color="green", alpha=0.5, label='Area plot')
plt.title("Fill Between Plot Example")
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
plt.legend()
plt.show()
我们可以看到一个plt.legend()
,这个是 Matplotlib 图形库中的一个函数,用于给图表添加图例。图例用于解释图中的每个数据系列代表什么,它会显示数据系列的标签和对应的颜色或形状。
当你在图表中绘制多个数据系列时,通过在 plot()
、scatter()
、bar()
等函数中使用 label
参数为每个数据系列添加标签,然后调用 plt.legend()
,Matplotlib 会自动创建图例。
例如:
plt.plot(x, y1, label='Series 1')
plt.plot(x, y2, label='Series 2')
plt.legend()
在这个例子中,将会在图表中显示两个数据系列的图例,分别标记为 “Series 1” 和 “Series 2”。如果不指定位置,Matplotlib 将尝试找到最不碍事的位置放置图例(通常是图表的角落)。你也可以通过传递参数给 plt.legend()
来指定图例的位置,例如 plt.legend(loc='upper right')
会将图例放在图表的右上角。
- 散点图 (
scatter
):x
,y
: x和y轴上的数据点。s
: 数据点的大小(可选)。c
: 数据点的颜色(可选)。alpha
: 图表的透明度(可选)。marker
: 表示数据点样式的字符串(可选)。marker
参数用于指定每个数据点的形状。这个参数可以是多种预定义形状的字符串代码,例如:'o'
: 圆圈's'
: 正方形'^'
: 上三角形'>'
: 右三角形'+'
: 加号'x'
: 叉号'D'
: 菱形
- 梯步图 (
step
):x
,y
: x和y轴上的数据点。where
: 指定步进发生的位置(‘pre’、‘post’、‘mid’),默认是’pre’。where='pre'
: 每个阶梯的开始处对齐于 x 轴上的对应点。where='post'
: 每个阶梯的结束处对齐于 x 轴上的对应点。where='mid'
: 每个阶梯的中间对齐于 x 轴上的对应点。
linewidth
或lw
: 线宽(可选)。
- 条形图 (
bar
):x
,y
: x轴上的坐标和每个条形的高度。width
: 条形的宽度(可选)。align
: 条形的对齐方式(‘center’ 或 ‘edge’)。alpha
: 条形的透明度(可选)。
- 面积图 (
fill_between
):x
: x轴上的数据点。y1
,y2
: 在x轴上填充区域的两个y轴数据序列,通常y2
是x
的函数。color
: 填充的颜色(可选)。alpha
: 填充的透明度(可选)。
直方图
n = np.random.randn(100000)
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
#figsize=(12, 4)说明了画板的长和宽
axes[0].hist(n)
axes[0].set_title("Default histogram")
axes[0].set_xlim((min(n), max(n)))
axes[1].hist(n, cumulative=True, bins=50)
axes[1].set_title("Cumulative detailed histogram")
axes[1].set_xlim((min(n), max(n)))
这段代码是用 Matplotlib 库绘制直方图的示例。这里首先生成了一个包含 100000 个服从标准正态分布的随机数的数组 n
,然后创建了一个包含两个画布的画板,用于绘制两种不同类型的直方图。
- 第一个画布(
axes[0]
)显示的是标准直方图,它展示了数据的分布情况。hist(n)
函数用于绘制n
的直方图,set_title
设置标题,set_xlim
设置 x 轴的范围,使其从n
的最小值到最大值。 - 第二个画布(
axes[1]
)显示的是累积直方图,通过设置cumulative=True
实现。累积直方图展示了小于或等于每个 x 值的观测值的累积频率。这里同样使用hist
函数绘制直方图,设置了 50 个桶(bins
),以便更详细地展示数据的累积分布。标题和 x 轴范围的设置与第一个画布相同。
雷达图
fig = plt.figure(figsize=(6, 6))
ax = fig.add_axes([0.0, 0.0, .6, .6], polar=True)
t = np.linspace(0, 2 * np.pi, 100)
ax.plot(t, t, color='blue', lw=3)
`等高线图
alpha = 0.7
phi_ext = 2 * np.pi * 0.5
def flux_qubit_potential(phi_m, phi_p):
return 2 + alpha - 2 * np.cos(phi_p) * np.cos(phi_m) - alpha * np.cos(phi_ext - 2*phi_p)
phi_m = np.linspace(0, 2*np.pi, 100)
phi_p = np.linspace(0, 2*np.pi, 100)
X, Y = np.meshgrid(phi_p, phi_m)
Z = flux_qubit_potential(X, Y).T
fig, ax = plt.subplots()
cnt = ax.contour(Z, cmap=plt.cm.RdBu, vmin=abs(Z).min(),
vmax=abs(Z).max(), extent=[0, 1, 0, 1])