matplotlib:如何添加透明背景的第二坐标轴?
定义数据
x = np.linspace(0,2*np.pi,100)
y = 2*np.sin(x)
绘图
fig = plt.figure()
ax = plt.axes()
fig.add_subplot(ax)
ax.plot(x,y)
添加第二个坐标轴
newax = plt.axes(axisbg='none')
我遇到了一个错误,提示 ValueError: Unknown element o
,尽管这和我接下来要描述的做的事情是一样的。我也发现这样做是可以的(没有错误),也能实现同样的效果:
newax = plt.axes()
fig.add_subplot(newax)
newax.set_axis_bgcolor('none')
不过,这样做会把原始图形的背景颜色变成“灰色”(或者说图形的背景颜色变成其他颜色)?我不太明白,因为我以为这样做会让新的坐标轴背景透明,只显示坐标轴和图形周围的框。即使我换个顺序,结果也是一样:
plt.close('all')
fig = plt.figure()
newax = plt.axes()
fig.add_subplot(newax)
newax.set_axis_bgcolor('none')
ax = plt.axes()
fig.add_subplot(ax)
ax.plot(x,y)
这让我感到惊讶,因为我以为一个背景会覆盖在另一个上,但无论如何,似乎是新的坐标轴背景在显示(或者至少这是我看到的颜色)。
这到底是怎么回事呢?
1 个回答
其实你并不是在添加一个新的坐标轴。
Matplotlib 检测到那个位置已经有一个图形在了,所以它返回的是原来的图形,而不是一个新的坐标轴对象。
(你可以自己检查一下。ax
和 newax
会是同一个对象。)
虽然可能没有必要这样做,但如果你真的想要,下面是方法。
(另外,不要先调用 newax = plt.axes()
然后再调用 fig.add_subplot(newax)
,这样做是重复的。)
补充:在更新版的 matplotlib(我想是 >=1.2)中,你可以通过在 fig.add_subplot
中使用 label
参数来实现和下面示例相同的效果。例如:newax = fig.add_subplot(111, label='some unique string')
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
# If you just call `plt.axes()` or equivalently `fig.add_subplot()` matplotlib
# will just return `ax` again. It _won't_ create a new axis unless we
# call fig.add_axes() or reset fig._seen
newax = fig.add_axes(ax.get_position(), frameon=False)
ax.plot(range(10), 'r-')
newax.plot(range(50), 'g-')
newax.axis('equal')
plt.show()
当然,这看起来很糟糕,但这正是你想要的……
我从你之前的问题猜测,你只是想添加第二个 x 轴?如果是这样,那就是完全不同的事情了。
如果你想让 y 轴相互关联,可以这样做(有点啰嗦……):
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
newax = ax.twiny()
# Make some room at the bottom
fig.subplots_adjust(bottom=0.20)
# I'm guessing you want them both on the bottom...
newax.set_frame_on(True)
newax.patch.set_visible(False)
newax.xaxis.set_ticks_position('bottom')
newax.xaxis.set_label_position('bottom')
newax.spines['bottom'].set_position(('outward', 40))
ax.plot(range(10), 'r-')
newax.plot(range(21), 'g-')
ax.set_xlabel('Red Thing')
newax.set_xlabel('Green Thing')
plt.show()
如果你想要一个隐藏的、不关联的 y 轴,以及一个全新的 x 轴,可以这样做:
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2)
newax = fig.add_axes(ax.get_position())
newax.patch.set_visible(False)
newax.yaxis.set_visible(False)
for spinename, spine in newax.spines.iteritems():
if spinename != 'bottom':
spine.set_visible(False)
newax.spines['bottom'].set_position(('outward', 25))
ax.plot(range(10), 'r-')
x = np.linspace(0, 6*np.pi)
newax.plot(x, 0.001 * np.cos(x), 'g-')
plt.show()
注意,任何在 newax
上绘制的图形的 y 轴值是不会显示的。
如果你愿意,你甚至可以更进一步,拥有独立的 x 轴和 y 轴(我不太确定这样做的意义,但看起来挺酷的……):
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2, right=0.85)
newax = fig.add_axes(ax.get_position())
newax.patch.set_visible(False)
newax.yaxis.set_label_position('right')
newax.yaxis.set_ticks_position('right')
newax.spines['bottom'].set_position(('outward', 35))
ax.plot(range(10), 'r-')
ax.set_xlabel('Red X-axis', color='red')
ax.set_ylabel('Red Y-axis', color='red')
x = np.linspace(0, 6*np.pi)
newax.plot(x, 0.001 * np.cos(x), 'g-')
newax.set_xlabel('Green X-axis', color='green')
newax.set_ylabel('Green Y-axis', color='green')
plt.show()
你也可以在图的底部添加一个额外的脊柱。有时候这样更简单,尤其是当你不想在上面显示刻度或数字时。虽然我不想过多宣传自己的回答,但这里有个示例:如何在 matplotlib 中绘制多个 X 或 Y 轴?
最后,如果你想通过特定的变换将不同的 x 轴和 y 轴关联起来,一定要看看 寄生坐标轴示例。