FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

matplotlib dynamic plotting · Issue #7759 · matplotlib/matplotlib · GitHub

Repository navigation

matplotlib dynamic plotting #7759

Closed
Closed

Description

Hi, after computer change, matplotlib don't work dynamically.
Before, it was able to update the figure at each iteration of a loop. Today only the last data are plotted.
Configuration :
HP zBook 15 G3 with NVidia Quadro

###Bug report

Bug summary

A figure inside a loop are not updated at each step

Code for reproduction

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(128)
plt.figure(1)
plt.ion()
plt.hold(False)
for it in range(5):
    plt.plot(x, x+it)
    plt.draw()

plt.ioff()
plt.show()

Expected outcome

  • I expect to see one plot at each step of the for loop

Matplotlib version
1.5.1

Python version
3.5.2

OS
Ubuntu 16.04 LTS

  • All of them had been installed from Ubuntu repository using synaptic

Activity

  1. petehuang commented on Jan 7, 2017

    Contributor

    I think you may need to add plt.pause(0.01) after plt.draw() - can you try that?

  2. MpCamp commented on Jan 7, 2017

    Author
  3. petehuang commented on Jan 7, 2017

    Contributor

    I'm entirely the wrong person to ask for the "why", but I'm glad it works! I just shuttled around StackOverflow for the answer :)

  4. tacaswell commented on Jan 7, 2017

    Member

    'why' is a bit of a long question (see #4779 for an old PR trying to document all of the details). In very short, we made many of the GUI embedding more asynchronous, that is calling plt.draw calls fig.canvas.draw_idle() which asks the GUI to re-render the figure. If you never turn control over to the GUI event loop to process it's events, then it does not have a chance to update it's self (you will also note that while your code is running you can not pan/zoom the figure).

    Doing

    import matplotlib.pyplot as plt
    plt.ion()
    import numpy as np
    
    x = np.arange(128)
    fig, ax = plt.subplots()
    
    for it in range(5):
        ax.plot(x, x+it)
        # fig.canvas.draw_idle()  # required to work on mpl < 1.5
        fig.canvas.flush_events()
        time.sleep(1)
    
    plt.ioff()
    plt.show()

    should do what you want.

  5. MpCamp commented on Jan 8, 2017

    Author
  6. petehuang commented on Jan 8, 2017

    Contributor

    👍

    Should we close this?

  7. MpCamp commented on Jan 8, 2017

    Author
  8. maxgittelman commented on Oct 25, 2017

    Hey guys, any idea on how to fix my equivalent MatplotlibDeprecationWarning. I realized I essentially have the exact same problem except on a larger scale?

    I have set up a server that will read in live data and produce two 3d plots. You can run this simulated code below (instead of reading in the data from the client).

    import matplotlib.pyplot as plt
    from threading import Thread, Lock, Condition
    import random, time, socket
    from mpl_toolkits.mplot3d import Axes3D
    import numpy as np
    
    
    class Plotter:
        def __init__(self):
    
            # temp list of data received by server
            self.data = [[] for i in range(3)]
    
            # threading variables
            self.mutex = Lock()
            self.points_received = 0
            self.cv = Condition()
    
            # initialize figure
            self.fig = plt.figure()
            self.run_plot = False
            self.ax = self.fig.add_subplot(111, projection='3d')
            self.ax.set_xlim(0, 1)
            self.ax.set_ylim(0, 1)
            self.ax.set_zlim(0, 1)
            plt.ion()
            plt.show()
    
        # This just simulates reading from a socket.
        def data_listener(self):
            while True:
                time.sleep(1)
                with self.mutex:
                    new_data = [random.random() for i in range(3)]
    
                    # append new data to be plotted and check max/min to update axes limits
                    for axis in range(3):
                        self.data[axis].append(new_data[axis])
    
        def sub_plot(self):
            # wait until ready, <Enter> is pressed
            self.cv.acquire()
            while not self.run_plot:
                self.cv.wait()  # I think this causes the plot to not respond before hitting <Enter>
            self.cv.release()
    
            while self.run_plot:
                time.sleep(0.01)
                with self.mutex:
                    try:
                        # add data and clear graph
                        self.ax.scatter(self.data[0], self.data[1], self.data[2])
                        self.data = [[] for i in range(3)]
    
                        plt.pause(0.000001)
                        # self.fig.canvas.flush_events()
                    except:
                        print ("error")
    
        def cmdline_input(self):
            # Start then End Plot
            for status in ["start", "end"]:
                text_start = raw_input("Hit <Enter> to " + status + " plotting")
                while text_start != "":
                    print "Wrong input"
                    text_start = raw_input("Hit <Enter> to " + status + " plotting")
    
                self.cv.acquire()
                if status == "start":
                    self.run_plot = True
                elif status == "end":
                    self.run_plot = False
                self.cv.notify()
                self.cv.release()
    
        def run(self):
            d = Thread(target=self.data_listener)
            d.start()
    
            # start cmdline input
            c_start = Thread(target=self.cmdline_input)
            c_start.start()
    
            # subplot
            self.sub_plot()
    
    
    if __name__ == '__main__':
        p = Plotter()
        p.run()
    

    You guys have a better handle on how to fix this issue. Currently when I run the live plot (randomly sending over numbers), I can change the viewing angle with my cursor but I can't zoom in or out. I tried adding in self.fig.canvas.flush_events() after plt.pause(0.000001) but that didn't seem to functionally change anything.

    I also noticed that when my plot isn't receiving live data, the window is unresponsive. I.e. If you try to maximize the window or change the window size the whole screen gets blurred. I have a feeling that this has something to do with me putting the plotting thread to sleep but maybe there's a simple fix?

  9. tacaswell commented on Oct 26, 2017

    Member

    This question is probably better sent to the mailing list (matplotlib-users@python.org ; you will have to subscribe to post).

    #4779 may also be informative reading.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL