我尝试绘制一个图表,显示化学反应的进展。进度本身(时间或反应步骤)应该可以使用滑块进行更改。 我到目前为止的代码:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.25)
fig.canvas.set_window_title('Reaktionsfortschritt')
t0 = 0
t = np.arange(0, t0, .5)
k0 = 0.17
a = np.exp(- k0 * t)
l, = plt.plot(t, a, lw=3, color='crimson')
plt.axis([0, 20, 0, 1])
axrs = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor='lightblue')
srs = Slider(axrs, 'Reaktionsschritte', 0, 20, valinit=0)
def xval(*args):
x = srs.val
t = np.arange(0, x, 0.5)
#l.set_ydata(np.exp(- 0.6 * t))
#plt.plot(t, a)
fig.canvas.draw_idle()
srs.on_changed(xval)
plt.show()
据我所知,使用xval函数更新了plot-range(t)。但是,没有图表的绘图。
我尝试使用plt.plot(t, a)
和l.set_ydata(...)
进行重新绘制。
好的,现在我添加了描述产品形成的第二个功能(b)。我也以与更新功能相同的方式添加了该功能。结果我得到一个非常奇怪的行为:使用滑块,我只能在正x方向绘图,例如在那里我不会回去。绘制图表后,它就会赢得' undraw'减小滑块值时。有什么建议吗?
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.25)
fig.canvas.set_window_title('Reaktionsfortschritt')
t = np.arange(0, 0, .5)
k0 = 0.17
a = np.exp(- k0 * t)
b = 1 - np.exp(- k0 * t)
# plot
l, = plt.plot(t, a, lw=3, color='crimson')
m, = plt.plot(t, b, lw=3, color='dodgerblue')
plt.axis([0, 20, 0, 1])
plt.grid(True)
axrs = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor='lightblue')
srs = Slider(axrs, 'Zeit', 0, 20, valinit=0)
def update(x):
t = np.arange(0, x, 2)
ax.lines.pop(0) # remove previous line plot
ax.plot(t, np.exp(- k0 * t), lw=3, color='crimson')
ax.plot(t, 1 - np.exp(- k0 * t), lw=3, color='dodgerblue')
fig.canvas.draw()
srs.on_changed(update)
plt.show()
答案 0 :(得分:2)
假设你在x轴上有时间并且想要每次更改由同一个函数创建的绘图的最长时间,我想出了这个:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.25)
fig.canvas.set_window_title('Reaktionsfortschritt')
t0 = 0
t = np.arange(0, t0, .5)
k0 = 0.17
a = np.exp(- k0 * t)
l, = ax.plot(t, a, lw=3, color='crimson')
plt.axis([0, 20, 0, 1])
axrs = plt.axes([0.25, 0.1, 0.65, 0.03])
srs = Slider(axrs, 'Reaktionsschritte', 0, 20, valinit=0)
def update(x):
t0 = x
t = np.arange(0, t0, .5)
ax.lines.pop(0) # remove previous line plot
ax.plot(t, np.exp(- k0 * t), lw=3, color='crimson') # plot new one
fig.canvas.draw()
srs.on_changed(update)
plt.show()
查看更改Slider值时的作用,并告诉我这是否是您想要它做的。
要编辑:
添加第二个绘图时,您有两个lines
个对象。在运行代码之后(在触摸Slider之前)尝试直接打印ax.lines
并看到它确实是两个lines
的列表。然后调用ax.lines.pop(0)
并查看列表中是否弹出了一个元素。这就是上面的代码所做的事情,每次触摸Slider时都会从axes
对象ax
中删除行(因为之后调用了update
),在调用{{ 1}}导致以前的情节消失。如果您现在触摸Slider一次,则会向fig.canvas.draw()
添加两个新的lines
,并且只会移除一个ax
。这就是为什么你认为没有回头的原因
因此,如果您现在添加了第二个图,则只需使用ax.lines
从列表ax.lines.pop(0)
中弹出两次,代码就可以正常运行; - )