plot函数怎么用:从基础绘图到常见参数设置

运营资讯4小时前发布 jdkjadmin
0 00
plot函数怎么用:从基础绘图到常见参数设置

plot函数怎么用:从基础绘图到常见参数设置

在 Python 中,plot 通常指 Matplotlib 的 matplotlib.pyplot.plot,用于绘制折线及由数据点构成的线条图。它适合展示随时间变化的指标、实验测量值、函数曲线,以及多组数据之间的趋势差异。本文围绕这个函数说明基本语法、常用参数、坐标轴设置和常见问题。

Matplotlib 还有面向对象接口,例如 Axes.plot。两者的绘图参数基本一致:pyplot.plot 会作用于当前坐标轴,ax.plot 则明确作用于指定的坐标轴。简单脚本中前者简洁;需要多个子图、封装绘图函数或管理复杂图表时,后者通常更清晰。

一、安装与最小示例

如果环境中尚未安装 Matplotlib,可以在终端执行:

python -m pip install matplotlib

下面是一个完整的折线图示例。代码会创建图表、绘制数据、添加标题和坐标轴标签,并显示结果:

import matplotlib.pyplot as plt

days = [1, 2, 3, 4, 5]
temperature = [18, 20, 19, 23, 22]

plt.plot(days, temperature)
plt.title("Daily temperature")
plt.xlabel("Day")
plt.ylabel("Temperature (C)")
plt.show()

plt.plot(days, temperature) 将 days 作为 x 坐标,将 temperature 作为 y 坐标,并用线连接各个数据点。plt.show() 用于显示图形;在 Jupyter 等交互环境中,图形有时会自动显示,但在普通脚本中显式调用更稳妥。

二、plot 的基本语法与数据规则

常见调用形式如下:

plt.plot(y)
plt.plot(x, y)
plt.plot(x, y, "r--")
plt.plot(x, y, color="steelblue", linestyle="--", marker="o")

只传入一个数据序列时,它被解释为 y 值,x 值默认是从 0 开始的整数序号。例如 plt.plot([4, 7, 5]) 对应的点是 (0, 4)、(1, 7)、(2, 5)。传入两个序列时,第一个是 x,第二个是 y。

对于一维 x、y 数据,通常要求两者包含相同数量的点。下面的写法会因长度不匹配而报错:

x = [1, 2, 3]
y = [10, 20]
plt.plot(x, y)

绘图数据可以是 Python 列表、NumPy 数组,以及许多可转换为数组的序列。实际项目中应检查数据形状和缺失值,尤其是在从文件、接口或表格读取数据后。数据内容不适合直接作为绘图参数传入时,应先明确转换规则,而不是依赖隐式类型转换。

三、在一张图中绘制多条线

最直观的办法是多次调用 plot。每次调用都会在当前坐标轴中添加一条或多条线:

import matplotlib.pyplot as plt

months = [1, 2, 3, 4, 5, 6]
sales_a = [12, 15, 14, 18, 20, 23]
sales_b = [10, 11, 13, 16, 17, 19]

plt.plot(months, sales_a, label="Product A")
plt.plot(months, sales_b, label="Product B")
plt.xlabel("Month")
plt.ylabel("Sales")
plt.title("Monthly sales")
plt.legend()
plt.show()

label 是线条在图例中显示的名称,调用 plt.legend() 才会显示图例。若没有为线条设置合适的标签,图例可能为空或不能准确说明各条线的含义。

也可以把二维 y 数据交给一次 plot 调用。对于常见的二维数组,Matplotlib 会按列或按行将数据解释为多条线,具体取决于数据形状及 x 的形状。因此,使用二维数据时应先确认数组的行列含义;若希望代码意图更明确,逐列调用 plot 往往更容易维护。

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(5)
y = np.array([
    [1, 3, 2],
    [2, 4, 3],
    [3, 5, 4],
    [4, 6, 5],
    [5, 7, 6],
])

for column in range(y.shape[1]):
    plt.plot(x, y[:, column], label=f"Series {column + 1}")

plt.legend()
plt.show()

四、颜色、线型、标记点和格式字符串

plot 支持通过位置参数中的格式字符串快速设置颜色、线型和标记。例如:

plt.plot(x, y, "ro--")

这里的格式字符串表示红色(ro)和虚线(--)。格式字符串是简写形式;当图表需要精确控制或多人维护时,推荐使用具名参数:

plt.plot(
    x,
    y,
    color="darkorange",
    linestyle="--",
    linewidth=2,
    marker="o",
    markersize=6,
    label="Observed"
)

常见参数包括:

  • color:线条颜色,可以使用 Matplotlib 支持的颜色名、十六进制颜色值等。
  • linestyle:线型,常见值包括 "-"(实线)、"--"(虚线)、":"(点线)和 "-."(点划线)。
  • linewidth:线宽,通常是正数,单位为 point。
  • marker:数据点标记,例如 "o"、"s"、"^"。设为 None 或不设置时,不额外绘制标记。
  • markersize:标记大小。
  • alpha:透明度,数值范围通常为 0 到 1,0 表示完全透明,1 表示不透明。
  • label:图例文本。

参数名称和可用值应以当前 Matplotlib 版本的 API 文档为准。不要假定所有颜色缩写、标记形状或其他样式名称都可用;无效值会导致异常。格式字符串适合快速探索,但不宜把多个含义不清的简写堆在一起。格式字符串与显式样式参数同时设置时,也可能出现重复指定或冲突,尽量选择一种方式表达样式。

五、设置标题、坐标轴范围和刻度

标题和坐标轴标签可以用 title、xlabel、ylabel 设置。使用 pyplot 接口时,常见做法如下:

plt.title("Model error")
plt.xlabel("Epoch")
plt.ylabel("Error")
plt.xlim(0, 100)
plt.ylim(0, 1)
plt.grid(True)
plt.show()

xlim 和 ylim 设置坐标轴显示范围。它们改变的是可见区域,不会筛选或删除原始数据。限制范围可能隐藏区间外的数据,因此在制作报告时应避免让读者误以为图中展示了全部数据。

如果要指定刻度位置,可使用 xticks 或 yticks。刻度标签较长时,可以旋转标签,避免重叠:

labels = ["Jan", "Feb", "Mar", "Apr"]
values = [5, 8, 6, 10]

plt.plot(range(len(values)), values, marker="o")
plt.xticks(range(len(labels)), labels, rotation=30)
plt.tight_layout()
plt.show()

tight_layout() 会尝试调整子图边距,减少标题和刻度标签被裁切的情况,但不能保证解决所有复杂布局问题。保存图片时也可使用 bbox_inches="tight",让输出边界尽量包含图中内容:

plt.savefig("chart.png", dpi=150, bbox_inches="tight")

在交互窗口中可以先 show() 再保存,但在脚本和自动化任务中,通常建议先调用 savefig,再调用 show,以避免某些后端在显示后关闭或清空当前图形。

六、使用面向对象接口绘图

当图中有多个坐标轴时,面向对象接口能减少“当前坐标轴”状态带来的混淆。以下示例创建左右两个子图:

import matplotlib.pyplot as plt

x = [0, 1, 2, 3]
y1 = [2, 3, 5, 4]
y2 = [8, 6, 7, 9]

fig, axes = plt.subplots(1, 2, figsize=(9, 3))

axes[0].plot(x, y1, marker="o")
axes[0].set_title("Series A")
axes[0].set_xlabel("x")
axes[0].set_ylabel("y")

axes[1].plot(x, y2, color="green")
axes[1].set_title("Series B")
axes[1].set_xlabel("x")
axes[1].set_ylabel("y")

fig.tight_layout()
plt.show()

plt.subplots 返回图形对象 fig 和坐标轴对象 axes。之后调用 axes[0].plot 或 axes[1].plot,可以明确指定数据绘制到哪个子图。plot 本身会返回创建的线条对象列表(Line2D 对象),需要后续调整线条时可以保存返回值:

lines = plt.plot([0, 1, 2], [2, 1, 3], label="score")
line = lines[0]
line.set_linewidth(3)
plt.legend()
plt.show()

七、日期、缺失值与数据顺序

绘制日期序列时,可以直接使用 Python 的日期对象,也可以先将字符串转换为日期。下面使用 datetime:

from datetime import datetime
import matplotlib.pyplot as plt

dates = [
    datetime(2024, 1, 1),
    datetime(2024, 1, 2),
    datetime(2024, 1, 3),
]
values = [3.2, 3.5, 3.1]

plt.plot(dates, values, marker="o")
plt.xlabel("Date")
plt.ylabel("Value")
plt.gcf().autofmt_xdate()
plt.show()

日期坐标的格式化和刻度密度会受 Matplotlib 的日期定位器、格式化器和版本等因素影响。若横轴标签过密,可以调整日期刻度,而不是把日期转成不具备时间语义的字符串序号后再绘图。

缺失值也需要特别处理。对于 NumPy 数组中的 NaN,Matplotlib 通常不会把该位置当作普通数值绘制,线条可能在缺失处断开。若先删除缺失数据,要同步处理 x 和 y,避免两个序列错位。不要在没有业务依据的情况下把缺失值一律替换为 0;这会改变图表表达的数据含义。

折线按照传入点的顺序连接,而不是自动按 x 值排序。如果 x 数据乱序,线条可能来回折返。若业务含义是按 x 轴递增展示,应先对 x 排序,并使用相同索引同步重排 y。

八、对数坐标与其他边界

当数据跨度很大时,可使用对数坐标,例如:

plt.plot([1, 10, 100, 1000], [2, 20, 200, 2000])
plt.xscale("log")
plt.yscale("log")
plt.show()

对数轴不能像普通线性轴那样表达零和负数。包含非正值时,可能出现警告、无效显示或数据被限制在可显示范围之外,具体表现取决于刻度设置和版本。使用对数轴之前,应检查数据是否满足正值要求,并在图表中清楚标明坐标轴尺度。

plot 适合按顺序连接数据点,不等同于散点图。如果只想展示离散点而不希望连接它们,可以不画线而只设置标记,或改用 scatter:

plt.plot(x, y, linestyle="None", marker="o")
# 或者
plt.scatter(x, y)
plt.show()

数据量极大时,绘制所有点可能使渲染和交互变慢,线条也可能因点过密而难以解读。应根据任务考虑合理抽样、聚合或使用专门的可视化方案;抽样或聚合会影响数据表达,必须符合分析目的,不能为了图形好看而隐去重要变化。

九、常见错误与排查方法

  • 出现长度不一致错误:检查 x 和 y 的元素数量,确认过滤缺失值时没有只处理其中一个序列。
  • 图形窗口没有显示:检查是否调用 plt.show(),并确认运行环境使用了合适的 Matplotlib 后端。无桌面的服务器可改为保存文件。
  • 中文显示为方框:当前系统或 Matplotlib 配置的字体可能不包含中文字符。需要选择系统中实际安装且支持中文的字体;字体名称因操作系统而异。
  • 图例为空或标签不对:检查每条线的 label,并确认调用了 legend()。
  • 点的连接顺序奇怪:检查 x 数据是否按预期排序,以及是否对 x、y 使用了同一排序索引。
  • 刻度或文字被裁切:尝试 tight_layout(),调整图形尺寸,或在保存时设置 bbox_inches="tight"。
  • 颜色、线型或参数报错:确认参数拼写和取值符合当前 Matplotlib 版本支持的范围。不要把其他绘图库的参数名直接套用到 Matplotlib。

十、数据输入与安全注意事项

Matplotlib 的 plot 用于把已经准备好的数据映射到图形中,本身不是用于执行 Python 代码的接口。正常情况下,绘制一组数值不会因为数值内容而执行其中包含的命令。不过,图表的安全性也取决于数据来源和上下游处理方式。

  • 不要对不可信输入使用 eval 来构造数据或绘图表达式。应采用受约束的解析方式,并验证输入类型、长度、数值范围和缺失值。
  • 不要把不可信文件直接交给可能执行对象反序列化的加载方式。例如,加载来源不可信的 pickle 文件可能带来代码执行风险;这不是 plot 函数本身的能力,而是数据加载环节的风险。
  • 处理外部数据时,应限制数据量和资源消耗,防止异常大的数组造成内存占用或绘图任务阻塞。
  • 将图表嵌入网页时,应根据网页技术栈正确转义标题、标签等文本,并遵循输出上下文的安全规则。Matplotlib 生成的图片与网页中的 HTML 文本不是同一种输出,不能因此忽略网页端的输入处理。

总结

掌握 plot,先记住三件事:只传一个序列时它表示 y,传入两个序列时分别表示 x 和 y;多次调用可以绘制多条线;用 color、linestyle、marker、label 等参数控制外观和图例。绘图前还要确认数据长度、形状、顺序和缺失值处理符合预期。简单图表可以使用 pyplot,多子图场景优先使用 Axes.plot,这样更容易维护,也更不容易把数据画到错误的坐标轴上。

© 版权声明

相关文章