matplotlib中寄生轴的网格线

2 投票
2 回答
3639 浏览
提问于 2025-04-15 19:10

你能在matplotlib中绘制带有副轴的图表网格线吗?

我尝试了这个,参考了网格和副轴的示例,但网格线没有绘制出来:

from mpl_toolkits.axes_grid.parasite_axes import SubplotHost
import matplotlib.pyplot as plt

fig = plt.figure(1)

host = SubplotHost(fig, 111)
fig.add_subplot(host)

par = host.twinx()

host.set_xlabel("Distance")
host.set_ylabel("Density")
par.set_ylabel("Temperature")

p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density")
p2, = par.plot([0, 1, 2], [0, 3, 2], label="Temperature")

host.axis["left"].label.set_color(p1.get_color())
par.axis["right"].label.set_color(p2.get_color())

host.grid(True)

host.legend()

plt.show()

2 个回答

3

对于这种类型的图表,想要一眼看出哪个对象应该调用'grid'并不总是那么简单。

有一种解决这个麻烦的方法——也就是在不改变任何代码的情况下,让你的图表上显示网格线,而不必担心哪个对象在调用'grid'——那就是编辑你的配置文件。这可能就足够让你完成你需要做的事情,但以防万一,下面是具体步骤:

  1. 下载示例的matplotlibrc文件,可以在这里找到,或者在site-packages/matplotlib/mpl-data/目录下找到你的副本;

  2. 在这个文件大约195行左右,寻找一个标题(作为注释)“### AXES”;

  3. 在这个标题下方五六行,你会看到'axes-grid'——取消这一行的注释,并把值设置为'True';

  4. 接着往下读这个文件,找到大约235行左右的标题'### GRIDS';

  5. 取消接下来的三行注释('grid.color','grid.linestyle',和'grid.linewidth'),并为这三个参数提供合理的值(我设置的是:'darkslategray',':',和0.7,分别对应颜色、线型和线宽。这里的':'表示我的网格线是虚线)。

  6. 将这个文件保存为:~/.matplotlibrc/matplotlibrc(换句话说,在你的用户目录下创建一个名为'.matplotlibrc'的文件夹,记得前面要有一个'.',然后把你编辑的这个文件命名为'matplotlibrc')。

就这样完成了。(缺点是当你创建不想要网格线的图表时——对于这种情况,我建议保持这个配置文件不变,必要时创建其他配置文件并在它们之间切换(可以参考相关的Matplotlib页面了解如何操作)。

另外,这个配置文件可以通过ipython轻松编辑——这可能是大多数用户的做法,但在这里可能会让人感到困惑。

5

根据这段讨论的内容,似乎在 .99 版本中存在一个 bug。

(我不太明白为什么 doug 的情况可以正常工作,但在我使用的 0.99.1.1-r1 版本中,无论怎么调整 rcParams 都不行。)

从那个链接中,解决办法是调用:

host.toggle_axisline(False)

toggle_axisline 的作用就是让 x 轴和 y 轴(它们负责在主线 mpl 中绘制刻度、刻度标签等)重新可见,同时让 axis["bottom"] 等变得不可见。

整个程序变成:

from mpl_toolkits.axes_grid.parasite_axes import SubplotHost
import matplotlib.pyplot as plt

fig = plt.figure(1)

host = SubplotHost(fig, 111)
fig.add_subplot(host)

par = host.twinx()

host.set_xlabel("Distance")
host.set_ylabel("Density")
par.set_ylabel("Temperature")

p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density")
p2, = par.plot([0, 1, 2], [0, 3, 2], label="Temperature")

host.axis["left"].label.set_color(p1.get_color())
par.axis["right"].label.set_color(p2.get_color())

host.toggle_axisline(False)
host.grid(True)

host.legend()

plt.show()

在这里输入图片描述

撰写回答