同时使用Matplotlib Slider和key_release_event [英] Using Matplotlib Slider and key_release_event concurrently

查看:98
本文介绍了同时使用Matplotlib Slider和key_release_event的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Matplotlib(带有'tkAgg'后端)来显示一系列图像中的图像.

我有一个Slider小部件设置,可让我滚动浏览图像序列-移动滑块可更改要显示的图像.

我还设置了一个mpl_connect,以专门从左右箭头键监听key_relese_events,该键调用相同的on_change()方法以前进至下一张图像或显示上一张图像.

这两种方法彼此之间都可以正常工作:当程序打开时,滑块被设置为显示堆栈中的第一张图像.然后,我可以来回移动滑块以显示不同的图像,也可以向右或向左按滑块以一幅图像来回移动.

我唯一的疑惑/问题是当我使用箭头键前进图像时,滑块值完全不变.因此,如果您向前按20次向右说20张图像,则将显示正确的图像,并且绘图标题也会相应更改,但是滑块仍会显示初始值或按箭头键时的原始值.

是否可以通过任何方式设置Slider小部件的值并更新屏幕以显示正确的值.我相信(尚未进行全面测试)您可以以myslider.val的形式访问滑块的值-但是,即使调用matplotlib.pyplot.draw(),设置该值似乎也无法链接到以图形方式显示的内容

TL; DR是否有一种方法可以将图中显示的Slider值绑定到本地变量,以便当该变量更改(正在显示新图像)时,Slider也将相应更改?

这实际上仅是出于美学价值,因为我之前提到过,我推进图像的两个控件都是相互独立的

以下是我的代码片段(不分先后顺序),它们是从我的源代码中剪下来的.我希望它的功能已经足够清楚了-

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提供解决方案的评论

Slider类slider.set_val()中有一个未公开的方法,可以完全满足我的需要-将滑块值设置为给定值,然后更新包含滑块的图形以使更改可见.

I am using Matplotlib (with 'tkAgg' backend) to display an image from a sequence of images.

I have a Slider widget setup to allow me to scroll through the image sequence - moving the slider changes which image is being displayed.

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.

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.

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

解决方案

Thanks to @tcaswell for the comment with the solution

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.

这篇关于同时使用Matplotlib Slider和key_release_event的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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