绘制x和y的副轴时缺少一个辅助标签
我之前在这个问题上学习了如何在同一个图表上绘制两个 x
轴和两个 y
轴,链接在这里:Matplotlib: 两个 x 轴和两个 y 轴。
这是一个简单的示例:
import matplotlib.pyplot as plt
import numpy as np
# Generate random data.
x1 = np.random.randn(50)
y1 = np.linspace(0, 1, 50)
x2 = np.random.randn(20)+15.
y2 = np.linspace(10, 20, 20)
# Plot both curves.
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.set_xlabel('x_1')
ax1.set_ylabel('y_1')
plt.plot(x1, y1, c='r')
ax2 = ax1.twinx().twiny()
ax2.set_xlabel('x_2')
ax2.set_ylabel('y_2')
plt.ylim(min(y2), max(y2))
ax2.plot(x2, y2, c='b')
plt.show()
这是输出结果:
右边的 y
轴和上面的 x
轴对应的是蓝色曲线。
如你所见,第二个 y
标签虽然已经定义了,但却没有显示出来。我尝试了很多不同的方法,但就是无法让它显示。难道我做错了什么吗?
补充:
显然,下面这行代码有问题:
ax2 = ax1.twinx().twiny()
如果我把它反过来写成这样:
ax2 = ax1.twiny().twinx()
那么第二个 x
标签就不会显示了。
1 个回答
4
基本上,发生的事情是你创建了一个第三个坐标轴对象,但你现在没有保存对它的引用。ax2
的可见y轴实际上是属于这个第三个坐标轴对象的。
你有几个选择。
- 保留对这个“隐藏”坐标轴对象的引用,并设置它的y标签。
- 不使用
twinx
和twiny
,而是直接在第一个坐标轴的位置创建一个新的坐标轴。
第二个选项稍微复杂一点,但好处是第二个图的y轴范围会自动调整,正如你所期望的那样。你不需要像现在这样手动设置它们。
无论如何,这里是第一个选项的一个例子:
import matplotlib.pyplot as plt
import numpy as np
# Generate random data.
x1 = np.random.randn(50)
y1 = np.linspace(0, 1, 50)
x2 = np.random.randn(20)+15.
y2 = np.linspace(10, 20, 20)
# Plot both curves.
fig, ax1 = plt.subplots()
ax1.set(xlabel='x_1', ylabel='y_1')
ax1.plot(x1, y1, c='r')
tempax = ax1.twinx()
ax2 = tempax.twiny()
ax2.plot(x2, y2, c='b')
ax2.set(xlabel='x_2', ylim=[min(y2), max(y2)])
tempax.set_ylabel('y_2', rotation=-90)
plt.show()
...这是第二个选项的一个例子:
import matplotlib.pyplot as plt
import numpy as np
def twinboth(ax):
# Alternately, we could do `newax = ax._make_twin_axes(frameon=False)`
newax = ax.figure.add_subplot(ax.get_subplotspec(), frameon=False)
newax.xaxis.set(label_position='top')
newax.yaxis.set(label_position='right', offset_position='right')
newax.yaxis.get_label().set_rotation(-90) # Optional...
newax.yaxis.tick_right()
newax.xaxis.tick_top()
return newax
# Generate random data.
x1 = np.random.randn(50)
y1 = np.linspace(0, 1, 50)
x2 = np.random.randn(20)+15.
y2 = np.linspace(10, 20, 20)
# Plot both curves.
fig, ax1 = plt.subplots()
ax1.set(xlabel='x_1', ylabel='y_1')
ax1.plot(x1, y1, c='r')
ax2 = twinboth(ax1)
ax2.set(xlabel='x_2', ylabel='y_2')
ax2.plot(x2, y2, c='b')
plt.show()
这两种方法的输出是完全相同的: