使用matplotlib时,绘图不会刷新以绘制新点

时间:2017-07-18 17:37:48

标签: python matplotlib plot draw

我试图创建一个在给定一组点([x,y])时更新的图,但是图形卡在第一个绘图点上并且不会绘制其余的数据。我循环了一个函数调用,但它在第一次调用时卡住了。我需要能够为函数提供多组单个x和y值,并将它们绘制成图形。

这是我到目前为止的代码。

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

它没有完全发挥作用。如果你在quit_case行上放置一个断点并在pycharm上的调试器上运行它,它会绘制图形&#34;正确&#34;。

1 个答案:

答案 0 :(得分:1)

请勿使用plt.show(block=False),不要使用time.sleep。相反,matplotlib提供animation module,可用于避免此处出现此类问题。

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