我的目标是在同一个窗口中创建三个子图。这些子图应该在一列中对齐,每一列在另一列之下。第一个子图不应该使用滑块小部件,其他两个应该,所以如果我将移动滑块,那么两个底部子图应该滚动。我最终得到了两个代码。我已经修改了一些代码来回答我的another question。棘手的部分是绘制部分,主要是作为试验和错误创建的:
#!/usr/bin/python
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
fig, ax = plt.subplots(nrows=2, ncols=1, sharex=True, sharey=False)
# 1. On which (sub)plots this option is apply to
# (already existed or also for subplots created in future)?
plt.subplots_adjust(bottom=0.25)
x_time = np.arange(0.0, 100.0, 0.1)
sin_s = np.sin(x_time)
cos_s = np.cos(x_time)
oscil = np.cos(2 * np.pi * x_time) * np.exp(-x_time)
sin_l, = plt.plot(x_time, sin_s, "bo-", label="sin")
cos_l, = plt.plot(x_time, cos_s, "r.-", label="cos")
# 2. On which plots this option is apply to
# (already existed or also for subplots created in future)?
plt.axis([0, 10, -1, 1])
####################################
# HERE COMES THE TRICKY PART WITH #
# TWO ALTERNATIVES - THE RESULT OF #
# TRIAL AND ERROR. PLEASE SEE CODE #
# SNIPPETS BELLOW #
####################################
axcolor = 'lightgoldenrodyellow'
axpos = plt.axes([0.2, 0.1, 0.65, 0.03], axisbg=axcolor)
spos = Slider(axpos, 'Pos', 0.1, 90.0)
def update(val):
pos = spos.val
# 3. No matter which index is chosen (0 or 1),
# it behaves exactly the same in both alternatives.
# How is this possible?
ax[0].axis([pos,pos+10,-1,1])
# ax[1].axis([pos,pos+10,-1,1])
fig.canvas.draw_idle()
spos.on_changed(update)
plt.show()
以下是我用于绘图的两个不同代码部分,这是我不理解的代码的试错部分:
# 1st alternative - this plot is scrollable:
ax[0].plot(x_time, oscil, "k-", label="oscilation")
ax[0].legend()
# 2nd alternative - this plot is not scrollable:
plt.subplot(211)
plt.plot(x_time, oscil, "k-", label="oscilation")
plt.title('A tale of 2 subplots')
plt.ylabel('Damped oscillation')
我试图将这些示例合并到我的最终解决方案中(有三个图可以从中滚动)。所以我在下一行中将nrows=2
更改为nrows=3
:
fig, ax = plt.subplots(nrows=2, ncols=1, sharex=True, sharey=False)
但是如果我使用第一种替代方案,那么所有三个子图都是可滚动的,而不是两个。如果我使用第二种替代方案,那么我只得到两个子图,而不是三个,其中一个是可滚动的而另一个不是。
您能否回答以下问题:
plt.subplots_adjust(bottom=0.25)
plt.axis([0, 10, -1, 1])
ax[0].axis([pos,pos+10,-1,1]) vs ax[1].axis([pos,pos+10,-1,1])
编辑,工作版本:
#!/usr/bin/python
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
plt.close('all')
fig, ax = plt.subplots(nrows=3, ncols=1)
plt.subplots_adjust(bottom=0.25)
########################################
x_time = np.arange(0.0, 100.0, 0.1)
oscil = np.cos(2 * np.pi * x_time) * np.exp(-x_time)
sin_s = 2*np.sin(x_time)
cos_s = np.cos(x_time)
########################################
ax[0].plot(x_time, oscil, "k-", label="oscilation")
ax[1].plot(x_time, sin_s, "bo-", label="sin")
ax[2].plot(x_time, cos_s, "r.-", label="cos")
########################################
ax[0].set_xlim([0, 10])
ax[1].set_ylim([-2, 2])
ax[2].set_ylim([-1, 1])
########################################
axcolor = 'lightgoldenrodyellow'
axpos = plt.axes([0.2, 0.1, 0.65, 0.03], axisbg=axcolor)
spos = Slider(axpos, 'Pos', 0.1, 90.0)
def update(val):
pos = spos.val
ax[1].axis([pos,pos+10,-2,2])
ax[2].axis([pos,pos+10,-1,1])
fig.canvas.draw_idle()
spos.on_changed(update)
plt.show()
答案 0 :(得分:1)
您的问题都可以通过matplotlib.figure
API documentation或matplotlib.pyplot
API documentation来解答。
1。此选项适用于哪些(子)图(已存在或未来创建的子图)?
plt.subplots_adjust(bottom=0.25)
所有可能的参数是:
subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
这些都更新了子图参数which are all documented here:
所有尺寸均为图宽度或高度底部的一小部分: 图的子图的底部。
因此,调用plt.subplots_adjust(bottom=0.25)
会使整个图的下边距(包含两个子图的区域) 25%的图形高度。
在此示例中,这是防止滑块与图形的其余部分发生碰撞所必需的。注释掉那条线,看看我的意思。
2. :此选项适用于哪些绘图(已存在或将来创建的子图)?
plt.axis([0, 10, -1, 1])
这将以[xmin, xmax, ymin, ymax]
的形式设置绘图的轴限制。 See this portion of the documentation
你设置plt
对象的轴有点奇怪 - 但是,这样做只在最后一个子图上设置了一次轴。
3. 无论选择哪个索引(0或1),它在两个备选方案中的行为都完全相同。这怎么可能?
ax[0].axis([pos,pos+10,-1,1])
ax[1].axis([pos,pos+10,-1,1])
您使用kwargs sharex=True
和sharey=False
创建了子图。由于最初创建的轴的ymin
为-1且ymax
为1,因此在任何一种情况下调用update
都不会更改轴。
由于您初始化了xmin
和xmax
(请参阅 2。),因此您在任何情况下都只更新了ymin=-1
和ymax=1
。在这种情况下,更新哪个轴无关紧要,因为sharex
行为将为两个轴更新此值。
但是,尝试更新y min和max - 更新轴属性在这种情况下将不相同。
4。最重要的是:如何让它适用于三个子图?
5. 最后是第一和第二替代方案之间的区别?
我不清楚你想在这做什么,所以我先从 5。开始。
# 1st alternative - this plot is scrollable:
ax[0].plot(x_time, oscil, "k-", label="oscilation")
ax[0].legend()
这会将您的振荡绘制到您调用plt.subplots
时创建的第一个子图中,因为您在ax[0]
上调用了绘图。调用ax[0].legend()
会根据您提供的标签和笔划绘制图例。
# 2nd alternative - this plot is not scrollable:
plt.subplot(211)
plt.plot(x_time, oscil, "k-", label="oscilation")
plt.title('A tale of 2 subplots')
plt.ylabel('Damped oscillation')
这会在第一个位置创建一个 new 子图 - 请参阅子图文档。它不会与您之前创建的图表共享轴。
我会把#4留给你,但如果你有任何具体问题,请告诉我。