使用滑块matplotlib更新x值

2024-05-20 15:28:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着画一个图表,来显示一个化学反应的进程。进度本身(时间或反应步骤)应该可以使用滑块进行更改。 到目前为止我掌握的代码是:

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()

据我所知,绘图范围(t)是使用xval函数更新的。但是,没有绘制图形。 我尝试了使用plt.plot(t, a)l.set_ydata(...)来回复。在

已编辑

好的,现在我添加了第二个函数(b),它描述了产物的形成。我也以同样的方式将函数添加到update函数中。结果,我得到了一个非常奇怪的行为:使用滑块,我只能在正x方向上绘图,例如,在那里我不能返回。一旦绘制了图形,在减小滑块值时不会“取消绘制”。有什么建议吗?在

^{pr2}$

Tags: 函数importplotmatplotlibasnpfig绘制
1条回答
网友
1楼 · 发布于 2024-05-20 15:28:02

假设你在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()

看看它在改变滑块值时会做什么,告诉我这是否是你想要它做的。在


编辑:
添加第二个绘图时,有两个lines对象。试着在运行代码之后(在触摸滑块之前)直接打印ax.lines,看看它实际上是两个lines的列表。然后调用ax.lines.pop(0)并看到从列表中弹出一个元素。上面的代码就是这样做的,每次您触摸滑块时,它都会从axes对象ax中删除行(因为这时会调用update),在调用fig.canvas.draw()后,会导致之前的绘图消失。如果现在触摸滑块一次,则会将两个新的lines添加到ax中,并且只删除一个。这就是为什么你认为没有回头路了。
因此,如果现在添加了第二个绘图,只需从列表ax.lines中弹出两次ax.lines.pop(0),代码就可以正常工作了;-)

相关问题 更多 >