同时使用 Matplotlib Slider 和 key_release_event
问题描述
我正在使用 Matplotlib(带有 'tkAgg' 后端)从一系列图像中显示图像.
I am using Matplotlib (with 'tkAgg' backend) to display an image from a sequence of images.
我有一个 Slider 小部件设置,允许我滚动图像序列 - 移动滑块会更改正在显示的图像.
I have a Slider widget setup to allow me to scroll through the image sequence - moving the slider changes which image is being displayed.
我还设置了一个 mpl_connect 来监听 key_relese_events,特别是从左右箭头键调用相同的 on_change() 方法来前进到下一个图像或显示上一个图像.
I also have an mpl_connect set to listen for key_relese_events specifically from the left and right arrow keys which calls the same on_change() method to either advance to the next image or show the previous image.
这两个都可以独立工作:当程序打开时,滑块设置为显示堆栈中的第一个图像.然后,我可以前后移动滑块以显示不同的图像,也可以按左右键来前后移动一个图像.
Both of these are working fine independent of eachother: when the program opens the slider is set to show to first image in the stack. I can then move the slider back and forth to show different images as well as press right or left to move back or forth by one image.
我唯一的疑虑/问题是,当我使用箭头键前进图像时,滑块值根本不会改变.因此,如果您通过按向右箭头 20 次向前推进 20 个图像,将显示正确的图像并且绘图标题会相应更改,但滑块仍会显示初始值或按下箭头键时的任何值.
My only qualm/question is that when I use the arrow keys to advance images the slider value doesn't change at all. So if you advance say 20 images forward by pressing right arrow 20 times, the correct image will be displayed and the plot titles change appropriately however the slider still shows the initial value or whatever value it was at when you pressed the arrow keys.
有什么方法可以设置 Slider 小部件的值并让屏幕更新以显示正确的值.我相信(尚未对其进行全面测试)您可以将滑块的值作为 myslider.val 访问 - 但是即使在调用 matplotlib.pyplot.draw() 之后,设置该值似乎也与图形显示的内容没有任何联系
Is there any way to set the value of the Slider widget and have the screen update to show the correct value. I believe (yet to fully test it) that you can access the value of the slider as myslider.val - however setting that value seems to have no link to what is being displayed graphically even after calling matplotlib.pyplot.draw()
TL;DR 有没有办法将图中显示的 Slider 值绑定到一个局部变量,以便当该变量更改(显示新图像)时,Slider 会相应更改?
TL;DR Is there a way to have the Slider value that is displayed in the figure be tied to a local variable so that when that variable changes (new image being displayed) the Slider will change accordingly?
这实际上只是为了美学价值,因为我之前提到过我用于推进图像的两个控件都相互独立
This is really only for aesthetic value as I previously mentioned that both of my controls for advancing the images work independent of eachother
以下是我的一些代码片段(无特定顺序)从我的源代码中截取.我希望它足够清楚这些功能在做什么-
Here are some snippets of my code (in no particular order) cut form my source. I hope its clear enough what the functions are doing-
def on_change(val):
"""
This function updates the LEEM image based on the slider value, val
This function is also called to update the image when an arrow key release is detected
"""
global curimg
curimg = energy_to_filenumber(round(val, 1))
img = all_dat[0:imheight-1, 0:imwidth-1,
curimg]
leemax.set_title("LEEM Image: " + str(elist[
int(energy_to_filenumber(round(val, 1)))]) + ' eV')
leemax.imshow(img, cmap=cm.Greys_r)
pylab.draw()
def arrow_key_image_control(event):
"""
This function takes an event from an mpl_connection
and listens for key release events specifically from
the keyboard arrow keys (left/right) and uses this
input to advance/reverse to the next/previous image.
"""
global curimg
minindex = 0
maxindex = all_dat.shape[2] - 1
if event.key == 'left':
if curimg - 1 >= minindex:
curimg -= 1
on_change(filenumber_to_energy(curimg))
else:
pass
elif event.key == 'right':
if curimg + 1 <= maxindex:
curimg += 1
on_change(filenumber_to_energy(curimg))
else:
pass
else:
pass
sld_ax = fig.add_axes([0.2, 0.025, 0.75, 0.02])
imsld = Slider(sld_ax, "Electron Energy",
elist[0], elist[len(elist)-1], elist[0], valfmt='%1.1f')
imsld.on_changed(on_change)
id2 = fig.canvas.mpl_connect('key_release_event', arrow_key_image_control)
解决方案
感谢@tcaswell 对解决方案的评论
Thanks to @tcaswell for the comment with the solution
Slider 类slider.set_val() 中有一个未记录的方法,它完全满足了我的需要 - 它将滑块值设置为给定值,然后更新包含滑块的图形,以便更改可见.
There is an undocumented method in the Slider class slider.set_val() which accomplishes exactly what I needed - it sets the slider values to a given value and then updates the figure containing the slider so the change is visible.
相关文章