Matplotlib - imshow twiny() 问题

3

我正在尝试在matplotlib的imshow()图中使用两个相互依赖的x轴。我将底部x轴设置为半径的平方,希望顶部的x轴只显示半径。到目前为止,我尝试了以下方法:

ax8 = ax7.twiny()
ax8._sharex = ax7
fmtr = FuncFormatter(lambda x,pos: np.sqrt(x) )
ax8.xaxis.set_major_formatter(fmtr)
ax8.set_xlabel("Radius [m]")

ax7 是 y 轴和底部的 x 轴(或半径的平方)。我没有像顶部的标记那样获得 sqrt(x_bottom),而是只获得从 0 到 1 的范围。我该如何解决这个问题?

非常感谢您提前的帮助。

1个回答

5

你误解了twiny的作用。它会创建一个完全独立的x轴,但与其他轴共享y轴。

你想要的是拥有不同的格式化程序,与联动轴(即共享轴限制但没有其他共享)。

简单的方法是手动设置双轴的轴限制:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter

fig, ax1 = plt.subplots()
ax1.plot(range(10))

ax2 = ax1.twiny()
formatter = FuncFormatter(lambda x, pos: '{:0.2f}'.format(np.sqrt(x)))
ax2.xaxis.set_major_formatter(formatter)

ax2.set_xlim(ax1.get_xlim())

plt.show()

enter image description here

然而,当您缩放或与图形交互时,您会注意到轴是不同步的。

您可以在相同位置添加一个带有共享x和y轴的轴,但是刻度格式化程序也将被共享。

因此,最简单的方法是使用寄生轴。

这里是一个快速示例:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
from mpl_toolkits.axes_grid1.parasite_axes import SubplotHost

fig = plt.figure()
ax1 = SubplotHost(fig, 1,1,1)
fig.add_subplot(ax1)

ax2 = ax1.twin()

ax1.plot(range(10))

formatter = FuncFormatter(lambda x, pos: '{:0.2f}'.format(np.sqrt(x)))
ax2.xaxis.set_major_formatter(formatter)

plt.show()

这个图表和之前的图表一开始看起来是相同的。但当你与图表交互(例如缩放/平移)时,它们之间的区别就会显现出来。


ax1.twiny() 创建 ax2,然后使用 ax1.get_xbound() 设置 ax2 的 x 轴范围,这样做有什么问题吗? - dashesy
似乎 twiny 的共用坐标轴未能传递缩放事件,因此如果存在共用坐标轴的子图,则设置边界无法解决问题。 - dashesy
+1,这是唯一可行的解决方案,设置边界是一个糟糕的hack。 - dashesy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接