From gregk3172 at outlook.com Thu Feb 2 08:36:03 2017 From: gregk3172 at outlook.com (Gregory Key) Date: Thu, 2 Feb 2017 13:36:03 +0000 Subject: [Matplotlib-users] Key Press and Key Release Events in TkInter In-Reply-To: References: Message-ID: Here is some code showing my problem. One uses the QT5Agg backend and one uses the TkAgg backend. The QT5Agg version behaves the way I would expect. You press a key, it fires the key_press event and then does nothing until you release the key. In the TkAgg version if you press a key and hold it there is a continuous stream of key_press, key_release events. from __future__ import print_function import matplotlib matplotlib.use('q t5agg') import matplotlib.pyplot as plt def on_key_press_event(event): ????print('you pressed %s' % event.key) def on_key_release_event(event): ????print('you released %s' % event.key) fig = plt.figure() fig.canvas.mpl_connect('key_press_event', on_key_press_event) fig.canvas.mpl_connect('key_release_event', on_key_release_event) plt.show() from __future__ import print_function import matplotlib matplotlib.use('tkagg') import matplotlib.pyplot as plt def on_key_press_event(event): ????print('you pressed %s' % event.key) def on_key_release_event(event): ????print('you released %s' % event.key) fig = plt.figure() fig.canvas.mpl_connect('key_press_event', on_key_press_event) fig.canvas.mpl_connect('key_release_event', on_key_release_event) plt.show() Thanks Greg Key On Tue, 2017-01-31 at 21:05 +0000, Gregory Key wrote: > I am running Python 3.5.2 and MatPlotLib 2.0.0 on Ubuntu 16.10. > > I am developing a program that uses matplotlib embedded in tkinter to > plot vibration data in a bode plot, phase and amplitude versus rotor > speed. I adapted the data browser given in the matplotlib > documentation > ????????????as example 91.2 data_browser.py to browse the data. The > browser worked but I wanted to modify it so that holding down the > next > or previous key would scroll through the data instead of having to > continously press and release the keys. My plan was to use the > key_press_event to start a timer which would call a scroll method and > then use the key_release event to stop the timer and stop scrolling. > I > couldn't make this scheme work so I did some investigating on the > key_press_event and key_release_event in tkinter. I used example 91.5 > keypress_demo.py given in the matplotlib documentation but I added a > key_release_event method to it. What I found was that the key events > don't work the way I would expect them to work. If you press and > release a key things work as expected. When a key is pressed the > key_press_event fires and when it is released the key_release_event > fires. If a key is pressed and held however the key_press_event fires > followed immediately by a key_release_event even though the key has > not > been released. As long as the key is held down it will continue to > fire > key_press_event followed by key_release_event. Is this the way it is > supposed to work? > > Thanks > Greg Key > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users at python.org > https://mail.python.org/mailman/listinfo/matplotlib-users From pmhobson at gmail.com Thu Feb 2 11:58:11 2017 From: pmhobson at gmail.com (Paul Hobson) Date: Thu, 2 Feb 2017 08:58:11 -0800 Subject: [Matplotlib-users] [matplotlib-devel] PyQt4 in Matplotlib v2.0.0 In-Reply-To: References: Message-ID: It appears that the build of matplotlib in conda-forge does not require pyqt5: https://github.com/conda-forge/matplotlib-feedstock/blob/master/recipe/meta.yaml So in your case, I would do: conda remove pyqt5 matplotlib conda install --channel=conda-forge matplotlib On Thu, Feb 2, 2017 at 8:48 AM, Benjamin Root wrote: > no, pyqt5 is not a dependency for matplotlib. this looks like a conda > packaging issue. > > Side note: the sourceforge mailing list is deprecated. Please use the > python.org version instead (you'll have to re-register). > > Ben Root > > > On Thu, Feb 2, 2017 at 11:43 AM, Osborn, Raymond wrote: > >> I just created a new conda environment with Matplotlib included, and it >> duly installed matplotlib: 2.0.0-np111py27_0. It installed PyQt5 by >> default, whereas I need PyQt4, but when I installed PyQt4 (conda install >> pyqt=4), it automatically downgraded Matplotlib to 1.5.1. >> -------- >> The following packages will be DOWNGRADED due to dependency conflicts: >> >> matplotlib: 2.0.0-np111py27_0 --> 1.5.1-np111py27_0 >> pyqt: 5.6.0-py27_2 --> 4.11.4-py27_4 >> qt: 5.6.2-0 --> 4.8.7-4 >> -------- >> Is PyQt5 really a dependency for Matplotlib v2? I have been testing >> release candidate versions of Matplotlib v2 without any problem. This will >> cause headaches to my users who want the latest features. >> >> Ray >> -- >> Ray Osborn, Senior Scientist >> Materials Science Division >> Argonne National Laboratory >> Argonne, IL 60439, USA >> Phone: +1 (630) 252-9011 <(630)%20252-9011> >> Email: ROsborn at anl.gov >> >> >> >> ------------------------------------------------------------ >> ------------------ >> Check out the vibrant tech community on one of the world's most >> engaging tech sites, SlashDot.org! http://sdm.link/slashdot >> _______________________________________________ >> Matplotlib-devel mailing list >> Matplotlib-devel at lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/matplotlib-devel >> > > > ------------------------------------------------------------ > ------------------ > Check out the vibrant tech community on one of the world's most > engaging tech sites, SlashDot.org! http://sdm.link/slashdot > _______________________________________________ > Matplotlib-devel mailing list > Matplotlib-devel at lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/matplotlib-devel > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From joferkington at gmail.com Thu Feb 2 15:07:12 2017 From: joferkington at gmail.com (Joe Kington) Date: Thu, 2 Feb 2017 14:07:12 -0600 Subject: [Matplotlib-users] Key Press and Key Release Events in TkInter In-Reply-To: References: Message-ID: That's a common "gotcha" when trying to detect a held key on a keyboard. Your operating system (or the actual hardware in your keyboard in some cases) interprets a held key as multiple keypresses and fires off events accordingly (e.g., that's why holding down "a" will give "aaaaaaaaa" when typing). I think Qt handles this automatically, but I could be wrong. Tk doesn't do it automatically. Usually, you'd detect a held key by keeping track of the either the last key press event or the time since the last keypress event. "Debouncing" is the term you'll want to search for. In tkinter, you can bind a function to fire after idle (effectively checking if the key was ever released). Alternatively, for the matplotlib side, I think you can bind to the idle event and do the same thing without needing to rely on anything tkinter-specific (Untested). Hope that helps a bit, anyway. -Joe On Tue, Jan 31, 2017 at 3:05 PM, Gregory Key wrote: > I am running Python 3.5.2 and MatPlotLib 2.0.0 on Ubuntu 16.10. > > I am developing a program that uses matplotlib embedded in tkinter to > plot vibration data in a bode plot, phase and amplitude versus rotor > speed. I adapted the data browser given in the matplotlib documentation > as example 91.2 data_browser.py to browse the data. The > browser worked but I wanted to modify it so that holding down the next > or previous key would scroll through the data instead of having to > continously press and release the keys. My plan was to use the > key_press_event to start a timer which would call a scroll method and > then use the key_release event to stop the timer and stop scrolling. I > couldn't make this scheme work so I did some investigating on the > key_press_event and key_release_event in tkinter. I used example 91.5 > keypress_demo.py given in the matplotlib documentation but I added a > key_release_event method to it. What I found was that the key events > don't work the way I would expect them to work. If you press and > release a key things work as expected. When a key is pressed the > key_press_event fires and when it is released the key_release_event > fires. If a key is pressed and held however the key_press_event fires > followed immediately by a key_release_event even though the key has not > been released. As long as the key is held down it will continue to fire > key_press_event followed by key_release_event. Is this the way it is > supposed to work? > > Thanks > Greg Key > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users at python.org > https://mail.python.org/mailman/listinfo/matplotlib-users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From gregk3172 at outlook.com Thu Feb 2 16:35:01 2017 From: gregk3172 at outlook.com (Gregory Key) Date: Thu, 2 Feb 2017 21:35:01 +0000 Subject: [Matplotlib-users] Key Press and Key Release Events in TkInter In-Reply-To: References: Message-ID: So basically in tkinter the key_release_event is useless. Thanks I'll do some experimenting with the information you have given me. On Thu, 2017-02-02 at 14:07 -0600, Joe Kington wrote: > That's a common "gotcha" when trying to detect a held key on a > keyboard.? Your operating system (or the actual hardware in your > keyboard in some cases) interprets a held key as multiple keypresses > and fires off events accordingly (e.g., that's why holding down "a" > will give "aaaaaaaaa" when typing). > > I think Qt handles this automatically, but I could be wrong. Tk > doesn't do it automatically. > > Usually, you'd detect a held key by keeping track of the either the > last key press event or the time since the last keypress event. > ?"Debouncing" is the term you'll want to search for.? In tkinter, you > can bind a function to fire after idle (effectively checking if the > key was ever released).? Alternatively, for the matplotlib side, I > think you can bind to the idle event and do the same thing without > needing to rely on anything tkinter-specific (Untested). > > Hope that helps a bit, anyway. > -Joe > > On Tue, Jan 31, 2017 at 3:05 PM, Gregory Key > wrote: > > I am running Python 3.5.2 and MatPlotLib 2.0.0 on Ubuntu 16.10. > > > > I am developing a program that uses matplotlib embedded in tkinter > > to > > plot vibration data in a bode plot, phase and amplitude versus > > rotor > > speed. I adapted the data browser given in the matplotlib > > documentation > > ? ? ? ? ? ? as example 91.2 data_browser.py to browse the data. The > > browser worked but I wanted to modify it so that holding down the > > next > > or previous key would scroll through the data instead of having to > > continously press and release the keys. My plan was to use the > > key_press_event to start a timer which would call a scroll method > > and > > then use the key_release event to stop the timer and stop > > scrolling. I > > couldn't make this scheme work so I did some investigating on the > > key_press_event and key_release_event in tkinter. I used example > > 91.5 > > keypress_demo.py given in the matplotlib documentation but I added > > a > > key_release_event method to it. What I found was that the key > > events > > don't work the way I would expect them to work. If you press and > > release a key things work as expected. When a key is pressed the > > key_press_event fires and when it is released the key_release_event > > fires. If a key is pressed and held however the key_press_event > > fires > > followed immediately by a key_release_event even though the key has > > not > > been released. As long as the key is held down it will continue to > > fire > > key_press_event followed by key_release_event. Is this the way it > > is > > supposed to work? > > > > Thanks > > Greg Key > > _______________________________________________ > > Matplotlib-users mailing list > > Matplotlib-users at python.org > > https://mail.python.org/mailman/listinfo/matplotlib-users > > > > From ssinhaonline at gmail.com Thu Feb 2 16:32:28 2017 From: ssinhaonline at gmail.com (Deep Sinha) Date: Thu, 02 Feb 2017 21:32:28 +0000 Subject: [Matplotlib-users] Help regarding matplotlib multicolored lines - attached StackOverflow question In-Reply-To: References: Message-ID: Hi, I needed some help tweaking a multicolored line with matplotlib. I adopted tacaswell's answer on StackOverflow at http://stackoverflow.com/a/30125761/3566440 When I do the steps exactly like its explained in the answer, I am able to replicate it. However, my case is a bit different. I have a dataframe with timeseries as it's index, and 'perc99_99' as a set of Z-scores. [image: Inline image 1] I modified the SO answer to the best of my knowledge and this is what the code looks like: fig, ax = plt.subplots() # Index of dataframe = timestamps x = day_avg_zscore.index.values # Z score of 99th percentiles y = day_avg_zscore['perc99_99'].values # Threshold at Z-score = 2, using helper function lc = threshold_plot(ax, x, y, 2, 'k', 'r') ax.axhline(2, color='k', ls='--') lc.set_linewidth(3) plt.show() I left the helper function intact: import numpy as np import matplotlib.pyplot as plt from matplotlib.collections import LineCollection from matplotlib.colors import ListedColormap, BoundaryNorm def threshold_plot(ax, x, y, threshv, color, overcolor): """ Helper function to plot points above a threshold in a different color Parameters ---------- ax : Axes Axes to plot to x, y : array The x and y values threshv : float Plot using overcolor above this value color : color The color to use for the lower values overcolor: color The color to use for values over threshv """ # Create a colormap for red, green and blue and a norm to color # f' < -0.5 red, f' > 0.5 blue, and the rest green cmap = ListedColormap([color, overcolor]) norm = BoundaryNorm([np.min(y), threshv, np.max(y)], cmap.N) # Create a set of line segments so that we can color them individually # This creates the points as a N x 1 x 2 array so that we can stack points # together easily to get the segments. The segments array for line collection # needs to be numlines x points per line x 2 (x and y) points = np.array([x, y]).T.reshape(-1, 1, 2) segments = np.concatenate([points[:-1], points[1:]], axis=1) # Create the line collection object, setting the colormapping parameters. # Have to set the actual values used for colormapping separately. lc = LineCollection(segments, cmap=cmap, norm=norm) lc.set_array(y) ax.add_collection(lc) ax.set_xlim(np.min(x), np.max(x)) ax.set_ylim(np.min(y)*1.1, np.max(y)*1.1) return lc Here's what I get as an output: [image: Inline image 2] What am I missing? I'm using Anaconda Python2.7 and Jupyter Notebook. Thank you! - Deep -- Sent from my phone. Please forgive typos and other forms of brevity. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image.png Type: image/png Size: 44013 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image.png Type: image/png Size: 14568 bytes Desc: not available URL: From gregk3172 at outlook.com Thu Feb 2 21:26:56 2017 From: gregk3172 at outlook.com (Gregory Key) Date: Fri, 3 Feb 2017 02:26:56 +0000 Subject: [Matplotlib-users] Key Press and Key Release Events in TkInter In-Reply-To: References: Message-ID: Bingo! Searching for 'key debounce in tkinter' was what I needed. I think I have found a solution. Thanks! Greg Key On Thu, 2017-02-02 at 21:35 +0000, Gregory Key wrote: > So basically in tkinter the key_release_event is useless. > > Thanks I'll do some experimenting with the information you have given > me. > > On Thu, 2017-02-02 at 14:07 -0600, Joe Kington wrote: > > That's a common "gotcha" when trying to detect a held key on a > > keyboard.? Your operating system (or the actual hardware in your > > keyboard in some cases) interprets a held key as multiple > > keypresses > > and fires off events accordingly (e.g., that's why holding down "a" > > will give "aaaaaaaaa" when typing). > > > > I think Qt handles this automatically, but I could be wrong. Tk > > doesn't do it automatically. > > > > Usually, you'd detect a held key by keeping track of the either the > > last key press event or the time since the last keypress event. > > ?"Debouncing" is the term you'll want to search for.? In tkinter, > > you > > can bind a function to fire after idle (effectively checking if the > > key was ever released).? Alternatively, for the matplotlib side, I > > think you can bind to the idle event and do the same thing without > > needing to rely on anything tkinter-specific (Untested). > > > > Hope that helps a bit, anyway. > > -Joe > > > > On Tue, Jan 31, 2017 at 3:05 PM, Gregory Key > > > > wrote: > > > I am running Python 3.5.2 and MatPlotLib 2.0.0 on Ubuntu 16.10. > > > > > > I am developing a program that uses matplotlib embedded in > > > tkinter > > > to > > > plot vibration data in a bode plot, phase and amplitude versus > > > rotor > > > speed. I adapted the data browser given in the matplotlib > > > documentation > > > ? ? ? ? ? ? as example 91.2 data_browser.py to browse the data. > > > The > > > browser worked but I wanted to modify it so that holding down the > > > next > > > or previous key would scroll through the data instead of having > > > to > > > continously press and release the keys. My plan was to use the > > > key_press_event to start a timer which would call a scroll method > > > and > > > then use the key_release event to stop the timer and stop > > > scrolling. I > > > couldn't make this scheme work so I did some investigating on the > > > key_press_event and key_release_event in tkinter. I used example > > > 91.5 > > > keypress_demo.py given in the matplotlib documentation but I > > > added > > > a > > > key_release_event method to it. What I found was that the key > > > events > > > don't work the way I would expect them to work. If you press and > > > release a key things work as expected. When a key is pressed the > > > key_press_event fires and when it is released the > > > key_release_event > > > fires. If a key is pressed and held however the key_press_event > > > fires > > > followed immediately by a key_release_event even though the key > > > has > > > not > > > been released. As long as the key is held down it will continue > > > to > > > fire > > > key_press_event followed by key_release_event. Is this the way it > > > is > > > supposed to work? > > > > > > Thanks > > > Greg Key > > > _______________________________________________ > > > Matplotlib-users mailing list > > > Matplotlib-users at python.org > > > https://mail.python.org/mailman/listinfo/matplotlib-users > > > > > > > > > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users at python.org > https://mail.python.org/mailman/listinfo/matplotlib-users From gregk3172 at outlook.com Fri Feb 3 13:32:16 2017 From: gregk3172 at outlook.com (Gregory Key) Date: Fri, 3 Feb 2017 18:32:16 +0000 Subject: [Matplotlib-users] Key Press and Key Release Events in TkInter In-Reply-To: References: Message-ID: I got excited too quickly. Searching the internet for 'key debounce in tkinter' did indeed returned several hits with sample code, some of them very elaborate. The problem is none of them worked on my computer! From Joe's previous comments and the samples I found I finally got inspiration. As usual with Python and matplotlib the solution turned out to be simple. Using the TkAgg backend on my computer and holding down a key fires a continuous stream of key_pressed and key_released events as long as the key is down. The solution was to let the first key_pressed event start a timer whose callback performs the task I want done, then I let the automatic key_pressed and key_released events just increment counters. In the timer callback I check for equality of the two counters. After the final key_release the counters will be equal so I stop the timer and reset the counters. Depending on the timer interval and the key repeat rate there are times that the callback falls between the key_press and the key_release which causes the callback to stop the timer but if the key is still down the next key_press event just starts the timer and it's callback again and keeps going without any noticeable hesitation. The Python code that works on my computer is shown below: """ Created on Thu Feb??2 07:22:19 2017 adapted from a matplotlib example """ import matplotlib matplotlib.use('tkagg') import matplotlib.pyplot as plt key_pressed = 0 key_released = 0 def on_key_press(event): ????""" ????Look for a right or left arrow key. ????If it is the first key press start the timer. ????Increment the key_pressed counter. ????""" ????global key_pressed ????global key_released ????if event.key not in ('right', 'left'): ????????return ????if key_pressed is 0: ????????print('starting timer') ????????timer1.start(interval=30) ????key_pressed += 1 ????print('\ninside onpress') ????print('key_pressed =', key_pressed) ????print('key_released =', key_released) def on_key_release(event): ????""" ????All this does is increment the key_released counter. ????""" ????global key_pressed ????global key_released ????if event.key not in ('right', 'left'): ????????return ????key_released += 1 ????print('\ninside onrelease') ????print('key_pressed =', key_pressed) ????print('key_released =', key_released) def scroll(): ????""" ????Scroll the data cursor or something ????""" ????global key_pressed ????global key_released ????print('\ninside scroll') ????print('key_pressed =', key_pressed) ????print('key_released =', key_released) ????if key_pressed is key_released: ????????print('\ntimer stopped') ????????key_pressed = 0??????# reset the counters for next keypress ????????key_released = 0 ????????# returning False stops the timer ????????return False fig = plt.figure() fig.canvas.mpl_connect('key_press_event', on_key_press) fig.canvas.mpl_connect('key_release_event', on_key_release) timer1 = fig.canvas.new_timer() timer1.add_callback(scroll) plt.show() Greg Key On Fri, 2017-02-03 at 02:26 +0000, Gregory Key wrote: > Bingo! Searching for 'key debounce in tkinter' was what I needed. I > think I have found a solution. Thanks! > > Greg Key > > On Thu, 2017-02-02 at 21:35 +0000, Gregory Key wrote: > > So basically in tkinter the key_release_event is useless. > > > > Thanks I'll do some experimenting with the information you have > > given > > me. > > > > On Thu, 2017-02-02 at 14:07 -0600, Joe Kington wrote: > > > That's a common "gotcha" when trying to detect a held key on a > > > keyboard.? Your operating system (or the actual hardware in your > > > keyboard in some cases) interprets a held key as multiple > > > keypresses > > > and fires off events accordingly (e.g., that's why holding down > > > "a" > > > will give "aaaaaaaaa" when typing). > > > > > > I think Qt handles this automatically, but I could be wrong. Tk > > > doesn't do it automatically. > > > > > > Usually, you'd detect a held key by keeping track of the either > > > the > > > last key press event or the time since the last keypress event. > > > ?"Debouncing" is the term you'll want to search for.? In tkinter, > > > you > > > can bind a function to fire after idle (effectively checking if > > > the > > > key was ever released).? Alternatively, for the matplotlib side, > > > I > > > think you can bind to the idle event and do the same thing > > > without > > > needing to rely on anything tkinter-specific (Untested). > > > > > > Hope that helps a bit, anyway. > > > -Joe > > > > > > On Tue, Jan 31, 2017 at 3:05 PM, Gregory Key > > om > > > > > > > > > > wrote: > > > > I am running Python 3.5.2 and MatPlotLib 2.0.0 on Ubuntu 16.10. > > > > > > > > I am developing a program that uses matplotlib embedded in > > > > tkinter > > > > to > > > > plot vibration data in a bode plot, phase and amplitude versus > > > > rotor > > > > speed. I adapted the data browser given in the matplotlib > > > > documentation > > > > ? ? ? ? ? ? as example 91.2 data_browser.py to browse the data. > > > > The > > > > browser worked but I wanted to modify it so that holding down > > > > the > > > > next > > > > or previous key would scroll through the data instead of having > > > > to > > > > continously press and release the keys. My plan was to use the > > > > key_press_event to start a timer which would call a scroll > > > > method > > > > and > > > > then use the key_release event to stop the timer and stop > > > > scrolling. I > > > > couldn't make this scheme work so I did some investigating on > > > > the > > > > key_press_event and key_release_event in tkinter. I used > > > > example > > > > 91.5 > > > > keypress_demo.py given in the matplotlib documentation but I > > > > added > > > > a > > > > key_release_event method to it. What I found was that the key > > > > events > > > > don't work the way I would expect them to work. If you press > > > > and > > > > release a key things work as expected. When a key is pressed > > > > the > > > > key_press_event fires and when it is released the > > > > key_release_event > > > > fires. If a key is pressed and held however the key_press_event > > > > fires > > > > followed immediately by a key_release_event even though the key > > > > has > > > > not > > > > been released. As long as the key is held down it will continue > > > > to > > > > fire > > > > key_press_event followed by key_release_event. Is this the way > > > > it > > > > is > > > > supposed to work? > > > > > > > > Thanks > > > > Greg Key > > > > _______________________________________________ > > > > Matplotlib-users mailing list > > > > Matplotlib-users at python.org > > > > https://mail.python.org/mailman/listinfo/matplotlib-users > > > > > > > > > > > > > > _______________________________________________ > > Matplotlib-users mailing list > > Matplotlib-users at python.org > > https://mail.python.org/mailman/listinfo/matplotlib-users > > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users at python.org > https://mail.python.org/mailman/listinfo/matplotlib-users From gregk3172 at outlook.com Fri Feb 3 13:40:55 2017 From: gregk3172 at outlook.com (Gregory Key) Date: Fri, 3 Feb 2017 18:40:55 +0000 Subject: [Matplotlib-users] Key Press and Key Release Events in TkInter In-Reply-To: References: Message-ID: Sorry about that!?The line 'timer1.add_callback(scroll)' has to be in the on_key_pressed function. Here is the code that really does work on my machine: """ Created on Thu Feb??2 07:22:19 2017 adapted from a matplotlib example """ import matplotlib matplotlib.use('tkagg') import matplotlib.pyplot as plt key_pressed = 0 key_released = 0 def on_key_press(event): ????""" ????Look for a right or left arrow key. ????If it is the first key press start the timer. ????Increment the key_pressed counter. ????""" ????global key_pressed ????global key_released ????if event.key not in ('right', 'left'): ????????return ????if key_pressed is 0: ????????print('starting timer') ????????timer1.start(interval=30) ????????timer1.add_callback(scroll) ????key_pressed += 1 ????print('\ninside onpress') ????print('key_pressed =', key_pressed) ????print('key_released =', key_released) def on_key_release(event): ????""" ????All this does is increment the key_released counter. ????""" ????global key_pressed ????global key_released ????if event.key not in ('right', 'left'): ????????return ????key_released += 1 ????print('\ninside onrelease') ????print('key_pressed =', key_pressed) ????print('key_released =', key_released) def scroll(): ????""" ????Scroll the data cursor or something ????""" ????global key_pressed ????global key_released ????print('\ninside scroll') ????print('key_pressed =', key_pressed) ????print('key_released =', key_released) ????if key_pressed is key_released: ????????print('\ntimer stopped') ????????key_pressed = 0??????# reset the counters for next keypress ????????key_released = 0 ????????# returning False stops the timer ????????return False fig = plt.figure() fig.canvas.mpl_connect('key_press_event', on_key_press) fig.canvas.mpl_connect('key_release_event', on_key_release) timer1 = fig.canvas.new_timer() # This has to be reset inside the on_key_press function #timer1.add_callback(scroll) plt.show() On Fri, 2017-02-03 at 18:32 +0000, Gregory Key wrote: > I got excited too quickly. Searching the internet for 'key debounce > in > tkinter' did indeed returned several hits with sample code, some of > them very elaborate. The problem is none of them worked on my > computer! > From Joe's previous comments and the samples I found I finally got > inspiration. As usual with Python and matplotlib the solution turned > out to be simple. Using the TkAgg backend on my computer and holding > down a key fires a continuous stream of key_pressed and key_released > events as long as the key is down. The solution was to let the first > key_pressed event start a timer whose callback performs the task I > want > done, then I let the automatic key_pressed and key_released events > just > increment counters. In the timer callback I check for equality of the > two counters. After the final key_release the counters will be equal > so > I stop the timer and reset the counters. Depending on the timer > interval and the key repeat rate there are times that the callback > falls between the key_press and the key_release which causes the > callback to stop the timer but if the key is still down the next > key_press event just starts the timer and it's callback again and > keeps > going without any noticeable hesitation. > The Python code that works on my computer is shown below: > > """ > Created on Thu Feb??2 07:22:19 2017 > adapted from a matplotlib example > """ > > import matplotlib > matplotlib.use('tkagg') > import matplotlib.pyplot as plt > > key_pressed = 0 > key_released = 0 > > > def on_key_press(event): > ????""" > ????Look for a right or left arrow key. > ????If it is the first key press start the timer. > ????Increment the key_pressed counter. > ????""" > ????global key_pressed > ????global key_released > > ????if event.key not in ('right', 'left'): > ????????return > ????if key_pressed is 0: > ????????print('starting timer') > ????????timer1.start(interval=30) > ????key_pressed += 1 > ????print('\ninside onpress') > ????print('key_pressed =', key_pressed) > ????print('key_released =', key_released) > > > def on_key_release(event): > ????""" > ????All this does is increment the key_released counter. > ????""" > ????global key_pressed > ????global key_released > > ????if event.key not in ('right', 'left'): > ????????return > ????key_released += 1 > ????print('\ninside onrelease') > ????print('key_pressed =', key_pressed) > ????print('key_released =', key_released) > > > def scroll(): > ????""" > ????Scroll the data cursor or something > ????""" > ????global key_pressed > ????global key_released > > ????print('\ninside scroll') > ????print('key_pressed =', key_pressed) > ????print('key_released =', key_released) > ????if key_pressed is key_released: > ????????print('\ntimer stopped') > ????????key_pressed = 0??????# reset the counters for next keypress > ????????key_released = 0 > ????????# returning False stops the timer > ????????return False > > fig = plt.figure() > fig.canvas.mpl_connect('key_press_event', on_key_press) > fig.canvas.mpl_connect('key_release_event', on_key_release) > timer1 = fig.canvas.new_timer() > timer1.add_callback(scroll) > > plt.show() > > Greg Key > > On Fri, 2017-02-03 at 02:26 +0000, Gregory Key wrote: > > Bingo! Searching for 'key debounce in tkinter' was what I needed. I > > think I have found a solution. Thanks! > > > > Greg Key > > > > On Thu, 2017-02-02 at 21:35 +0000, Gregory Key wrote: > > > So basically in tkinter the key_release_event is useless. > > > > > > Thanks I'll do some experimenting with the information you have > > > given > > > me. > > > > > > On Thu, 2017-02-02 at 14:07 -0600, Joe Kington wrote: > > > > That's a common "gotcha" when trying to detect a held key on a > > > > keyboard.? Your operating system (or the actual hardware in > > > > your > > > > keyboard in some cases) interprets a held key as multiple > > > > keypresses > > > > and fires off events accordingly (e.g., that's why holding down > > > > "a" > > > > will give "aaaaaaaaa" when typing). > > > > > > > > I think Qt handles this automatically, but I could be wrong. Tk > > > > doesn't do it automatically. > > > > > > > > Usually, you'd detect a held key by keeping track of the either > > > > the > > > > last key press event or the time since the last keypress event. > > > > ?"Debouncing" is the term you'll want to search for.? In > > > > tkinter, > > > > you > > > > can bind a function to fire after idle (effectively checking if > > > > the > > > > key was ever released).? Alternatively, for the matplotlib > > > > side, > > > > I > > > > think you can bind to the idle event and do the same thing > > > > without > > > > needing to rely on anything tkinter-specific (Untested). > > > > > > > > Hope that helps a bit, anyway. > > > > -Joe > > > > > > > > On Tue, Jan 31, 2017 at 3:05 PM, Gregory Key > > > .c > > > > om > > > > > > > > > > > > > wrote: > > > > > I am running Python 3.5.2 and MatPlotLib 2.0.0 on Ubuntu > > > > > 16.10. > > > > > > > > > > I am developing a program that uses matplotlib embedded in > > > > > tkinter > > > > > to > > > > > plot vibration data in a bode plot, phase and amplitude > > > > > versus > > > > > rotor > > > > > speed. I adapted the data browser given in the matplotlib > > > > > documentation > > > > > ? ? ? ? ? ? as example 91.2 data_browser.py to browse the > > > > > data. > > > > > The > > > > > browser worked but I wanted to modify it so that holding down > > > > > the > > > > > next > > > > > or previous key would scroll through the data instead of > > > > > having > > > > > to > > > > > continously press and release the keys. My plan was to use > > > > > the > > > > > key_press_event to start a timer which would call a scroll > > > > > method > > > > > and > > > > > then use the key_release event to stop the timer and stop > > > > > scrolling. I > > > > > couldn't make this scheme work so I did some investigating on > > > > > the > > > > > key_press_event and key_release_event in tkinter. I used > > > > > example > > > > > 91.5 > > > > > keypress_demo.py given in the matplotlib documentation but I > > > > > added > > > > > a > > > > > key_release_event method to it. What I found was that the key > > > > > events > > > > > don't work the way I would expect them to work. If you press > > > > > and > > > > > release a key things work as expected. When a key is pressed > > > > > the > > > > > key_press_event fires and when it is released the > > > > > key_release_event > > > > > fires. If a key is pressed and held however the > > > > > key_press_event > > > > > fires > > > > > followed immediately by a key_release_event even though the > > > > > key > > > > > has > > > > > not > > > > > been released. As long as the key is held down it will > > > > > continue > > > > > to > > > > > fire > > > > > key_press_event followed by key_release_event. Is this the > > > > > way > > > > > it > > > > > is > > > > > supposed to work? > > > > > > > > > > Thanks > > > > > Greg Key > > > > > _______________________________________________ > > > > > Matplotlib-users mailing list > > > > > Matplotlib-users at python.org > > > > > https://mail.python.org/mailman/listinfo/matplotlib-users > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > Matplotlib-users mailing list > > > Matplotlib-users at python.org > > > https://mail.python.org/mailman/listinfo/matplotlib-users > > > > _______________________________________________ > > Matplotlib-users mailing list > > Matplotlib-users at python.org > > https://mail.python.org/mailman/listinfo/matplotlib-users > > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users at python.org > https://mail.python.org/mailman/listinfo/matplotlib-users From amit at phpandmore.net Sat Feb 4 03:30:43 2017 From: amit at phpandmore.net (Amit Yaron) Date: Sat, 4 Feb 2017 10:30:43 +0200 Subject: [Matplotlib-users] Matplotlib Docs Message-ID: If you want to know where to start learning MatPlotLib, click the following link: http://matplotlib.org/2.0.0/contents.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From yuri.sukhov at gmail.com Mon Feb 6 15:14:44 2017 From: yuri.sukhov at gmail.com (Yuri Sukhov) Date: Mon, 6 Feb 2017 22:14:44 +0200 Subject: [Matplotlib-users] What is Artist._animated used for in Matplotlib Message-ID: Hi all, I am writing my own Animation class for Matplotlib in order to use event-based animation and it's unclear how Artist._animated and associated set_animated() function affect rendering. My animation should use blitting and I took existing FuncAnimation class as a reference for my implementation. In this class _init_draw and _draw_frame methods, among other things, set _animated = True for each artist in self._drawn_artists if blitting is enabled: for a in self._drawn_artists: a.set_animated(self._blit) What is the reason for this operation? In what cases Artist._animated is used, and how it affects rendering with or without blitting? I have tested my implementation and I don't see any difference in behaviour with or without set_animated(): class DataAnimation(Animation): def __init__(self, fig, *args, **kwargs): super(DataAnimation, self).__init__(fig, event_source=event_source, *args, **kwargs) def new_frame_seq(self): return itertools.count() def _init_draw(self): self._drawn_artists = plot.init() for artist in self._drawn_artists: # <- do we need this? artist.set_animated(self._blit) def _draw_frame(self, frame_data): self._drawn_artists = plot.updated_artists for artist in self._drawn_artists: # <- do we need this? artist.set_animated(self._blit) Thanks! Yuri. -------------- next part -------------- An HTML attachment was scrubbed... URL: From tcaswell at gmail.com Mon Feb 6 16:03:47 2017 From: tcaswell at gmail.com (Thomas Caswell) Date: Mon, 06 Feb 2017 21:03:47 +0000 Subject: [Matplotlib-users] What is Artist._animated used for in Matplotlib In-Reply-To: References: Message-ID: See https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/axes/_base.py#L2355 It is used to exclude the 'animated' artists from the normal draw method which greatly simplifies getting a clean background image. Tom On Mon, Feb 6, 2017 at 3:15 PM Yuri Sukhov wrote: > Hi all, > > I am writing my own Animation class for Matplotlib in order to use > event-based animation and it's unclear how Artist._animated and associated > set_animated() function affect rendering. > > My animation should use blitting and I took existing FuncAnimation class > as a reference for my implementation. In this class _init_draw and > _draw_frame methods, among other things, set _animated = True for each > artist in self._drawn_artists if blitting is enabled: > > for a in self._drawn_artists: > a.set_animated(self._blit) > > What is the reason for this operation? In what cases Artist._animated is > used, and how it affects rendering with or without blitting? I have tested > my implementation and I don't see any difference in behaviour with or > without set_animated(): > > class DataAnimation(Animation): > def __init__(self, fig, *args, **kwargs): > super(DataAnimation, self).__init__(fig, > event_source=event_source, *args, **kwargs) > > def new_frame_seq(self): > return itertools.count() > > def _init_draw(self): > self._drawn_artists = plot.init() > for artist in self._drawn_artists: # <- do we need this? > artist.set_animated(self._blit) > > def _draw_frame(self, frame_data): > self._drawn_artists = plot.updated_artists > for artist in self._drawn_artists: # <- do we need this? > artist.set_animated(self._blit) > > Thanks! > > Yuri. > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users at python.org > https://mail.python.org/mailman/listinfo/matplotlib-users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From yuri.sukhov at gmail.com Tue Feb 7 14:15:47 2017 From: yuri.sukhov at gmail.com (Yuri Sukhov) Date: Tue, 7 Feb 2017 21:15:47 +0200 Subject: [Matplotlib-users] What is Artist._animated used for in Matplotlib In-Reply-To: References: Message-ID: Hi Thomas, Thank you for your response. Is it possible to find somewhere documentation with the details on how drawing is done in Matplotlib? Or maybe you can shed some light on this? Of course source code is here and I am reading it, but without knowing of what are the major steps of the process, it takes a lot of time to take all parts together. I looked at the _AxesBase.draw() method, and I can see that, if _animated is set for the artist, than it's excluded from rasterization (not sure if that is the right term). That does not tell me much, because I am not aware of the whole drawing process. I am not even sure, when is this draw() method called? It seems to me that _blit_draw() from Animation class calls a.axes.draw_artist(a), but that is a different method and it does not check _animation property for the artist. On Mon, Feb 6, 2017 at 11:03 PM, Thomas Caswell wrote: > See > https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/axes/_base.py#L2355 > > It is used to exclude the 'animated' artists from the normal draw method > which greatly simplifies getting a clean background image. > > Tom > > On Mon, Feb 6, 2017 at 3:15 PM Yuri Sukhov wrote: >> >> Hi all, >> >> I am writing my own Animation class for Matplotlib in order to use >> event-based animation and it's unclear how Artist._animated and associated >> set_animated() function affect rendering. >> >> My animation should use blitting and I took existing FuncAnimation class >> as a reference for my implementation. In this class _init_draw and >> _draw_frame methods, among other things, set _animated = True for each >> artist in self._drawn_artists if blitting is enabled: >> >> for a in self._drawn_artists: >> a.set_animated(self._blit) >> >> What is the reason for this operation? In what cases Artist._animated is >> used, and how it affects rendering with or without blitting? I have tested >> my implementation and I don't see any difference in behaviour with or >> without set_animated(): >> >> class DataAnimation(Animation): >> def __init__(self, fig, *args, **kwargs): >> super(DataAnimation, self).__init__(fig, >> event_source=event_source, *args, **kwargs) >> >> def new_frame_seq(self): >> return itertools.count() >> >> def _init_draw(self): >> self._drawn_artists = plot.init() >> for artist in self._drawn_artists: # <- do we need this? >> artist.set_animated(self._blit) >> >> def _draw_frame(self, frame_data): >> self._drawn_artists = plot.updated_artists >> for artist in self._drawn_artists: # <- do we need this? >> artist.set_animated(self._blit) >> >> Thanks! >> >> Yuri. >> _______________________________________________ >> Matplotlib-users mailing list >> Matplotlib-users at python.org >> https://mail.python.org/mailman/listinfo/matplotlib-users From tcaswell at gmail.com Tue Feb 7 17:37:05 2017 From: tcaswell at gmail.com (Thomas Caswell) Date: Tue, 07 Feb 2017 22:37:05 +0000 Subject: [Matplotlib-users] What is Artist._animated used for in Matplotlib In-Reply-To: References: Message-ID: http://www.aosabook.org/en/matplotlib.html is a reasonable starting point, it refers to 0.96, but the core of the library has not changed much. The very short version is that through a layer or two of in-direction when the figure is rendered, the canvas creates a renderer and pass it to `Figure.draw` which then recurses it's children calling `Artist.draw` which renders all of the artists to the canvas (which may represent a file or a bit map, which in the case of a GUI is then passed to the GUI toolkit and displayed on the screen). `draw_artist` is a helper-method on Axes to make doing blitting work easier. During `Axes.draw` it caches a reference to the renderer so that you can out-of-band render additional artists. See http://matplotlib.org/api/animation_api.html#funcanimation for a much longer explanation of how this works. Tom On Tue, Feb 7, 2017 at 2:16 PM Yuri Sukhov wrote: > Hi Thomas, > > Thank you for your response. Is it possible to find somewhere > documentation with the details on how drawing is done in Matplotlib? > Or maybe you can shed some light on this? Of course source code is > here and I am reading it, but without knowing of what are the major > steps of the process, it takes a lot of time to take all parts > together. > > I looked at the _AxesBase.draw() method, and I can see that, if > _animated is set for the artist, than it's excluded from rasterization > (not sure if that is the right term). That does not tell me much, > because I am not aware of the whole drawing process. I am not even > sure, when is this draw() method called? It seems to me that > _blit_draw() from Animation class calls a.axes.draw_artist(a), but > that is a different method and it does not check _animation property > for the artist. > > > On Mon, Feb 6, 2017 at 11:03 PM, Thomas Caswell > wrote: > > See > > > https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/axes/_base.py#L2355 > > > > It is used to exclude the 'animated' artists from the normal draw method > > which greatly simplifies getting a clean background image. > > > > Tom > > > > On Mon, Feb 6, 2017 at 3:15 PM Yuri Sukhov > wrote: > >> > >> Hi all, > >> > >> I am writing my own Animation class for Matplotlib in order to use > >> event-based animation and it's unclear how Artist._animated and > associated > >> set_animated() function affect rendering. > >> > >> My animation should use blitting and I took existing FuncAnimation class > >> as a reference for my implementation. In this class _init_draw and > >> _draw_frame methods, among other things, set _animated = True for each > >> artist in self._drawn_artists if blitting is enabled: > >> > >> for a in self._drawn_artists: > >> a.set_animated(self._blit) > >> > >> What is the reason for this operation? In what cases Artist._animated is > >> used, and how it affects rendering with or without blitting? I have > tested > >> my implementation and I don't see any difference in behaviour with or > >> without set_animated(): > >> > >> class DataAnimation(Animation): > >> def __init__(self, fig, *args, **kwargs): > >> super(DataAnimation, self).__init__(fig, > >> event_source=event_source, *args, **kwargs) > >> > >> def new_frame_seq(self): > >> return itertools.count() > >> > >> def _init_draw(self): > >> self._drawn_artists = plot.init() > >> for artist in self._drawn_artists: # <- do we need this? > >> artist.set_animated(self._blit) > >> > >> def _draw_frame(self, frame_data): > >> self._drawn_artists = plot.updated_artists > >> for artist in self._drawn_artists: # <- do we need this? > >> artist.set_animated(self._blit) > >> > >> Thanks! > >> > >> Yuri. > >> _______________________________________________ > >> Matplotlib-users mailing list > >> Matplotlib-users at python.org > >> https://mail.python.org/mailman/listinfo/matplotlib-users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jni.soma at gmail.com Wed Feb 22 18:19:55 2017 From: jni.soma at gmail.com (Juan Nunez-Iglesias) Date: Thu, 23 Feb 2017 10:19:55 +1100 Subject: [Matplotlib-users] Asyncio, Tk, and matplotlib Message-ID: <17128d7a-ca3e-4516-bf2e-a63bab022b21@Spark> Hi everyone, I?m new to both asynchronous programming and to GUI programming so please forgive any newbie mistakes in the below code. I?m developing a simple GUI app that takes some parameters from the user, then when the user clicks a button, launches some long-running task, *which includes making and saving a matplotlib plot*. When using the standard Tk `app.mainloop()`, this causes the application to become non-responsive while the long computation is running. So I figured I?d use this newfangled asyncio thnigy that everyone is talking about. =P I settled on modelling it after Guido?s own tkcrawl.py [1]_, which periodically ?manually" calls tkinter?s `update()` within the asyncio event loop. Unfortunately, when matplotlib is invoked in the asynchronous task, it crashes tkinter with the error: RuntimeError: main thread is not in main loop Apparently calling tk functions from anything other than the main thread is a big no-no. But, this is where I?m stuck: how do I asynchronously launch a long-running task that includes matplotlib plotting? Any ideas about how I can tweak my design so my app is responsive but tasks include making big plots? I?ve included sample code below. By swapping out ?fasync? for ?fsync?, you too can experience the frustration of a beach-balled or greyed out app ? but at least the app works! ;) Thanks! Juan. .. [1]?https://bugs.python.org/file43873/tkcrawl.py Minimal code: import asyncio import matplotlib matplotlib.use('TkAgg') import tkinter as tk from tkinter import ttk from skimage._shared._tempfile import temporary_file import numpy as np @asyncio.coroutine def _async(func, *args): ? ? loop = asyncio.get_event_loop() ? ? return (yield from loop.run_in_executor(None, func, *args)) STANDARD_MARGIN = (3, 3, 12, 12) def long_computation(): ? ? import time ? ? time.sleep(4) ? ? import matplotlib.pyplot as plt ? ? fig, ax = plt.subplots() ? ? ax.imshow(np.random.rand(500, 500)) ? ? with temporary_file(suffix='.png') as fname: ? ? ? ? fig.savefig(fname) class MainWindow(tk.Tk): ? ? def __init__(self): ? ? ? ? super().__init__() ? ? ? ? self.title('I gonna die') ? ? ? ? main = ttk.Frame(master=self, padding=STANDARD_MARGIN) ? ? ? ? main.grid(row=0, column=0, sticky='nsew') ? ? ? ? fsync = long_computation ? ? ? ? fasync = lambda: asyncio.ensure_future(_async(long_computation)) ? ? ? ? button = ttk.Button(master=main, padding=STANDARD_MARGIN, ? ? ? ? ? ? ? ? ? ? ? ? ? ? text='Run stuff', ? ? ? ? ? ? ? ? ? ? ? ? ? ? command=fasync) ? ? ? ? button.grid(row=0, column=0) ? ? ? ? main.pack() def tk_update(loop, app): ? ? try: ? ? ? ? app.update() ? ? except tk.TclError as e: ? ? ? ? loop.stop() ? ? ? ? return ? ? loop.call_later(.01, tk_update, loop, app) def main(): ? ? loop = asyncio.get_event_loop() ? ? app = MainWindow() ? ? #app.mainloop() ? ? tk_update(loop, app) ? ? loop.run_forever() if __name__ == '__main__': ? ? main() -------------- next part -------------- An HTML attachment was scrubbed... URL: From ludwig.schwardt at gmail.com Thu Feb 23 15:44:40 2017 From: ludwig.schwardt at gmail.com (Ludwig Schwardt) Date: Thu, 23 Feb 2017 22:44:40 +0200 Subject: [Matplotlib-users] Asyncio, Tk, and matplotlib Message-ID: Hi Juan, Funny that you should mention it... I was busy with the exact same thing today :-) It is as you said: the matplotlib GUI has to run on the main thread. The trick seems to be to start the asyncio loop in a second background thread and communicate with the GUI running on the main thread via a queue. I found this StackOverflow answer very helpful. As an aside, I eventually ditched asyncio for an even simpler threading + queue solution (being stuck in Python 2.7...). Cheers, Ludwig P.P.S. I have an old matplotlib GUI app that used to disable the button during the long-running task (run from the on_clicked callback) to indicate when the GUI becomes available again. This behaviour does not seem to work anymore on modern matplotlib, hence my need to investigate background threads :-) -------------- next part -------------- An HTML attachment was scrubbed... URL: From tcaswell at gmail.com Thu Feb 23 21:07:56 2017 From: tcaswell at gmail.com (Thomas Caswell) Date: Fri, 24 Feb 2017 02:07:56 +0000 Subject: [Matplotlib-users] Asyncio, Tk, and matplotlib In-Reply-To: References: Message-ID: Sorry I don't have time to write out a longer answer (with, you know, working code), but a of couple of rough thoughts from recent experience. - all GUI stuff must happen on the main thread (if you do threads), but for some backends `draw_idle()` maybe thread safe. - for asyncio no blocking part of the task should be slower than 1/10 a second (that is the time between subsequent calls to `yield from`/`yield`/`await`). Anything slower and you will need to push it out of the main thread/process. It brings a bunch of complexity, but I would look at something like dask. The futures look to have a `add_done_callback` method which you can use to bridge to an asyncio.Event that you can await on, (although you might run into some tornado vs asyncio issues). Looks like someone has already done the work of hiding multiprocess behind asyncio (https://github.com/dano/aioprocessing). Would not go with threads unless you have a lot of gil releasing code. - integrating asyncio and GUIs are about the same problem as integrating GUIs and the command line, you have two infinite loops that both want to run the show (and block while waiting for the slow human). I have been using https://github.com/NSLS-II/bluesky/blob/master/bluesky/utils.py#L684 to good effect at my day-job for keeping figures alive under asyncio, but we are mostly waiting for (motion control related) network / motion. You install a self-perpetuating 'call_later' on to the asyncio event loop that drains the GUI events (which lets all of their callbacks run and re-draws the figure). - A super embarrassing (but functional) qt example is where I use qt threads + ipyparallel is https://github.com/tacaswell/leidenfrost/blob/master/leidenfrost/gui/proc_gui.py In this case I let the GUI event loop run the show. Tom On Thu, Feb 23, 2017 at 3:45 PM Ludwig Schwardt wrote: > Hi Juan, > > Funny that you should mention it... I was busy with the exact same thing > today :-) > > It is as you said: the matplotlib GUI has to run on the main thread. The > trick seems to be to start the asyncio loop in a second background thread > and communicate with the GUI running on the main thread via a queue. I > found this StackOverflow answer > very helpful. > > As an aside, I eventually ditched asyncio for an even simpler threading + > queue solution (being stuck in Python 2.7...). > > Cheers, > > Ludwig > > P.P.S. I have an old matplotlib GUI app that used to disable the button > during the long-running task (run from the on_clicked callback) to indicate > when the GUI becomes available again. This behaviour does not seem to work > anymore on modern matplotlib, hence my need to investigate background > threads :-) > > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users at python.org > https://mail.python.org/mailman/listinfo/matplotlib-users > -------------- next part -------------- An HTML attachment was scrubbed... URL: