0

I would like my plot to be updated live. It gets a list from a function, the funktion is embedded in, the list constantly gets longer over time. Thus the plotting has to stop at a point and cant bean infnite loop. Furhermore the entire class is run in a loop.

This is the Code i came up with after days of research and programming, but unfortunatly i cant get the plpot to show up.

class LiveGraph():

    def __init__(self):

        fig = plt.figure()
        self.ax1 = fig.add_subplot(1,1,1)
        self.xar=[]
        self.yar=[]
        self.h1=self.ax1.plot(self.xar, self.yar)[0]

    def update_plot(self):
        graph_data=open("twitter-out.txt", "r")
        graph_data=list(graph_data)
        graph_data=graph_data[0].split(",")

        x=0
        y=0

        for l in graph_data:
            x+=1
            try:
                y=float(l)
            except BaseException as e:
                pass
            self.xar.append(x)
            self.yar.append(y)

        self.h1.set_xdata(self.xar)
        self.h1.set_ydata(self.yar)
        plt.draw()

I would like to have the plot show itself while the rest of the code continues in the background.

The Code is called from within a loop getting tweets:

class StdOutListener(StreamListener):  
    def on_data(self,data):
        try:
            all_data = json.loads(data)
            text=all_data["text"]

            temp_text=TextBlob(text)
            analysis=temp_text.sentiment.polarity

            output = open("twitter-out.txt","a")
            output.write(str(analysis))
            output.write(",")
            output.close()

            print("sucsess")

            live_graph=LiveGraph()
            live_graph.update_plot()

            return True

        except BaseException as e:
            print('Failed: ', str(e))

This loop is part of the tweepy libary and gets triggered each time a tweet is recieved.

Fabian
  • 63
  • 1
  • 13

1 Answers1

1

There's an interactive mode for matplotlib so you can detach drawing process from other code:

import matplotlib.pyplot as plt
plt.ion()
plt.plot([1,2,3]) # plots show here

# other stuff

Or you can call plt.show(block=False). From doc:

In non-interactive mode, display all figures and block until the figures have been closed; in interactive mode it has no effect unless figures were created prior to a change from non-interactive to interactive mode (not recommended). In that case it displays the figures but does not block.

A single experimental keyword argument, block, may be set to True or False to override the blocking behavior described above.

In your case you may change your last line to show(block=False).

Community
  • 1
  • 1
knh190
  • 2,744
  • 1
  • 16
  • 30
  • Thank you for your fast reply, unfortunatly the whole code mentioned above runns in a loop in another function. plt.show(block=False) gets 20 plots printed before throwing an error – Fabian May 21 '19 at 10:14
  • @Fabian How do you call it? Can you post the relevant code? – knh190 May 21 '19 at 10:35
  • @Fabian well, imo, it's better to save pngs to local directory because your drawing will obviously be quite frequent. And also you need to handle exceptions/ – knh190 May 21 '19 at 10:53
  • @Fabian Because there's no code to close the pop ups so you'll end with tons of opening windows for sure. Saving them to a directory and handle specific exceptions is more reasonable. – knh190 May 21 '19 at 10:58
  • The problem here, which i am facing is that noone ever has tried to print something life from the same code that generates the data to be printed in a loop. is there any possible solution to this ? – Fabian May 21 '19 at 11:00
  • @Fabian I cannot help without specific information but there's a post will possibly help: https://stackoverflow.com/questions/458209/is-there-a-way-to-detach-matplotlib-plots-so-that-the-computation-can-continue – knh190 May 21 '19 at 11:04