使用滑块 matplotlib 更新 x 值 [英] update x value using slider matplotlib

查看:79
本文介绍了使用滑块 matplotlib 更新 x 值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试绘制一个图表,显示化学反应的进程.进度本身(时间或反应步骤)应使用滑块更改.我到目前为止的代码:

I try to draw a graph, which show the progress of a chemical reaction. The progress itself (time or reactionsteps) should be changeable using a slider. The code I have so far:

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(...) 重新绘图.

As far as I understand the plot-range (t) is updated using the xval-function. However, there is no plotting of the graph. I tried both replotting using plt.plot(t, a) as well as l.set_ydata(...).

好的,现在我添加了描述产品形成的第二个函数 (b).我也以相同的方式向update-function添加了该函数.结果我得到了一个非常奇怪的行为:使用滑块,我只能在正x方向上进行绘制,例如那里我不回头.绘制图形后,减少滑块值时不会取消绘制".有什么建议吗?

Ok, so now I added a second function (b) that describes product formation. I added the function also in the same way to the update-function. As a result I get a very strange behaviour: using the slider, I can plot only in positive x-direction, e.g. there I no going back. Once the graph is drawn, it won't 'undraw' when reducing the slider value. Any suggestion why that is?

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

推荐答案

假设您在 x 轴上有时间并且想要更改每次由相同函数创建的绘图的最长时间,我想出了这个:

Assuming you have time on the x-axis and want to change the maximum time of your plot that is created by the same function every time, I came up with this:

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"(滑块)值时的操作,并告诉我这是否是您要执行的操作.

See what it does when changing the Slider value and let me know if this is what you wanted it to do.

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

To your edit:
When you add a second plot, you have two lines objects. Try to print ax.lines directly after you run the code (before touching the Slider) and see that it really is a list of two lines. Then call ax.lines.pop(0) and see that one element is popped from the list. That's what the above code does, it removes lines from the axes object ax every time you touch the Slider (because then update is called), which after calling fig.canvas.draw() leads to vanishing of previous plots. If you now touch the Slider once, then two new lines are added to ax and only one is removed. This is why you think there is no going back.
So if you now added a second plot, you just have to pop twice from the list ax.lines with ax.lines.pop(0) and the code works fine ;-)

这篇关于使用滑块 matplotlib 更新 x 值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆