简体   繁体   中英

Plot doesn't refresh to plot new points when using matplotlib

I'm trying to create a plot that updates when given a set of points ([x,y]) but the figure gets stuck on the first plot points and won't plot the rest of the data. I looped a function call but it gets stuck on the first call. I need to be able to give the function multiple sets of single x and y values, and have them plot in a graph.

This is the code I have so far.

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
from numpy import *
from time import sleep
import random as rd

class graphUpdater():

    def __init__(self):
        # Initialize arrays to be plotted
        self.xs = []
        self.ys = []

        style.use('fivethirtyeight') # Figure Style
        self.fig = plt.figure() # Initialize figure
        self.ax1 = self.fig.add_subplot(111) # Create a subplot
        # Ensure the figure auto-scales to fit all points. Might be overkill
        self.ax1.set_autoscalex_on(True)
        self.ax1.set_autoscaley_on(True)
        self.ax1.set_autoscale_on(True)
        self.ax1.autoscale(enable = True, axis = 'both', tight = False)
        self.ax1.autoscale_view(False, True, True)

    # Function that plots the arrays xs and ys. Also plots a linear regression of the data
    def plotPoint(self):
        self.ax1.clear() # Clears previous values to save memory
        xp = linspace(min(self.xs), max(self.xs)) # x-range for regression
        if(len(self.xs) > 1): # Conditional for regression, can't linearise 1 point
            p1 = polyfit(self.xs, self.ys, 1) # Get the coefficients of the polynomial (slope of line)
            self.ax1.plot(xp, polyval(p1, xp)) # Plot the line
        self.ax1.plot(self.xs, self.ys, "+") # Plot the raw data points
        self.ax1.set_xlabel('(L/A)*I') # Axis and title labels
        self.ax1.set_ylabel('V')
        self.ax1.set_title('DC Potential Drop')

    def appendPlot(self, x, y):
        self.xs.append(float(x)) # Append xs with x value
        self.ys.append(float(y)) # Append ys with y value
        self.plotPoint() # Call the plotPoint function to plot new array values
        plt.show(block=False) # Plot and release so graphs can be over written

# Call the function
plsWork = graphUpdater() # I'm very hopeful
i = 0
while(i < 50):
    plsWork.appendPlot(i, rd.randint(0, 20))
    i += 1
    sleep(0.1)
quit_case = input("Hit 'Enter' to Quit") # Conditional so the plot won't disappear

It doesn't work fully. If you put a breakpoint on the quit_case line and run it on debugger on pycharm it plots the graph "properly".

Don't use plt.show(block=False) and don't use time.sleep . Instead, matplotlib provides an animation module , which can be used to avoid such problems as here.

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
from numpy import *
from time import sleep
import random as rd
#%matplotlib notebook use in case of running this in a Jupyter notebook

class graphUpdater():

    def __init__(self):
        # Initialize arrays to be plotted
        self.xs = []
        self.ys = []

        style.use('fivethirtyeight') # Figure Style
        self.fig = plt.figure() # Initialize figure
        self.ax1 = self.fig.add_subplot(111) # Create a subplot
        # Ensure the figure auto-scales to fit all points. Might be overkill
        self.ax1.set_autoscalex_on(True)
        self.ax1.set_autoscaley_on(True)
        self.ax1.set_autoscale_on(True)
        self.ax1.autoscale(enable = True, axis = 'both', tight = False)
        self.ax1.autoscale_view(False, True, True)

    # Function that plots the arrays xs and ys. Also plots a linear regression of the data
    def plotPoint(self):
        self.ax1.clear() # Clears previous values to save memory
        xp = linspace(min(self.xs), max(self.xs)) # x-range for regression
        if(len(self.xs) > 1): # Conditional for regression, can't linearise 1 point
            p1 = polyfit(self.xs, self.ys, 1) # Get the coefficients of the polynomial (slope of line)
            self.ax1.plot(xp, polyval(p1, xp)) # Plot the line
        self.ax1.plot(self.xs, self.ys, "+") # Plot the raw data points
        self.ax1.set_xlabel('(L/A)*I') # Axis and title labels
        self.ax1.set_ylabel('V')
        self.ax1.set_title('DC Potential Drop')

    def appendPlot(self, x, y):
        self.xs.append(float(x)) # Append xs with x value
        self.ys.append(float(y)) # Append ys with y value
        self.plotPoint() # Call the plotPoint function to plot new array values

# Call the function
plsWork = graphUpdater() # I'm very hopeful

f = lambda i: plsWork.appendPlot(i, rd.randint(0, 20))

ani = animation.FuncAnimation(plsWork.fig, f, frames=50, interval=100, repeat=False)
plt.show()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM