3

I am using Matplotlib to plot a real time event in Anaconda prompt.
When I update plot by plt.draw() or plt.show(), I loose control of the thing I am doing. Plot window acts like its clicked and this blocks my other control on the command prompt.

I tried adding

plt.show(block=False)

but it didnt help.

The code is like below,

fig, ax = plt.subplots()
plt.ion()
plt.show(block=False)
while(True):
    ax.plot(y_plt_points,x_plt_points,'ro')
    plt.draw()
    plt.pause(0.01)
Tom Ron
  • 5,906
  • 3
  • 22
  • 38
Melih Dal
  • 393
  • 4
  • 12
  • By 'the thing I am doing' do you mean that you are trying to execute different parts of your script while the plot is updating? Or try to run code on the command prompt? – Novice May 15 '19 at 12:27
  • Any kind of task. It can writing a script in text editor, browsing the web etc. I loose my control over the text editor while matplotlib makes updates. I want it to silently update the graph in the background when I do other tasks in windows. – Melih Dal May 16 '19 at 07:56
  • Did the answer below help? have you tried the example on your computer? – Novice May 20 '19 at 10:32

2 Answers2

1

This link has an example of real time plotting with matplotlib. I think the main takeaway is that you don't need to use plt.show() or plt.draw() on every call to plot. The example uses set_ydata instead. Simalarly set_xdata can be used to update your x_axis variables. Code below

import matplotlib.pyplot as plt
import numpy as np

# use ggplot style for more sophisticated visuals
plt.style.use('ggplot')

def live_plotter(x_vec,y1_data,line1,identifier='',pause_time=0.1):
    if line1==[]:
        # this is the call to matplotlib that allows dynamic plotting
        plt.ion()
        fig = plt.figure(figsize=(13,6))
        ax = fig.add_subplot(111)
        # create a variable for the line so we can later update it
        line1, = ax.plot(x_vec,y1_data,'-o',alpha=0.8)        
        #update plot label/title
        plt.ylabel('Y Label')
        plt.title('Title: {}'.format(identifier))
        plt.show()

    # after the figure, axis, and line are created, we only need to update the y-data
    line1.set_ydata(y1_data)
    # adjust limits if new data goes beyond bounds
    if np.min(y1_data)<=line1.axes.get_ylim()[0] or np.max(y1_data)>=line1.axes.get_ylim()[1]:
    plt.ylim([np.min(y1_data)-np.std(y1_data),np.max(y1_data)+np.std(y1_data)])
# this pauses the data so the figure/axis can catch up - the amount of pause can be altered above
plt.pause(pause_time)

# return line so we can update it again in the next iteration
return line1

When I run this function on the example below I don't have any trouble using other applications on my computer

size = 100
x_vec = np.linspace(0,1,size+1)[0:-1]
y_vec = np.random.randn(len(x_vec))
line1 = []
i=0
while i<1000:
    i=+1
    rand_val = np.random.randn(1)
    y_vec[-1] = rand_val
    line1 = live_plotter(x_vec,y_vec,line1)
    y_vec = np.append(y_vec[1:],0.0)
Novice
  • 855
  • 8
  • 17
0

I think this is what you are looking for. I had a similar issue, fixed it by replacing:

plt.pause(0.01) with fig.canvas.flush_events()

A more detailed explanation found here: How to keep matplotlib (python) window in background?

Haze
  • 171
  • 3