Home > Software engineering >  Generating repeatedly updating graph (FuncAnimation - Matplotlib)
Generating repeatedly updating graph (FuncAnimation - Matplotlib)

Time:06-02

I am trying to write a code that will generate a graph that is being repeatedly updated and has twin axes (2 y-axis, sharing the same x-axis).

The code works well when I don't combine it with FuncAnimation, however when I try to do that I get an empty graph.


def animate(i):
    data=prices(a,b,c)    #function that gives a DataFrame with 2 columns and index
    plt.cla()   
    fig=plt.figure()
    ax = fig.add_subplot(111)
    ax.plot(data.index, data.value1)
    ax2 = ax.twinx()
    ax2.plot(data.index, data.value2)
    plt.gcf().autofmt_xdate()     
    plt.tight_layout()  

call = FuncAnimation(plt.gcf(), animate, 1000)  
plt.tight_layout()
plt.show
'''


I believe the error is in "call". Unfortunately, I don't know FuncAnimation so well.

CodePudding user response:

You can try something like this:

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import pandas as pd
from datetime import datetime, timedelta

def getPrices(i):
    return pd.DataFrame(index=[datetime.now()   timedelta(hours=i) for i in range(10)], data={'value1':range(10), 'value2':[(x   i) % 5 for x in range(10)]})

def doAnimation():
    fig=plt.figure()
    ax = fig.add_subplot(111)

    def animate(i):
        #data=prices(a,b,c)    #function that gives a DataFrame with 2 columns and index
        data = getPrices(i)

        plt.cla()
        ax.plot(data.index, data.value1)
        ax2 = ax.twinx()
        ax2.plot(data.index, data.value2)
        plt.gcf().autofmt_xdate()     
        plt.tight_layout()  
        return ax, ax2

    call = FuncAnimation(plt.gcf(), animate, 1000)  
    plt.show()

doAnimation()

UPDATE:

Though this works in my environment, OP in a comment indicated it doesn't work and the following warning is raised:

UserWarning: Animation was deleted without rendering anything. This is most likely not intended. To prevent deletion, assign the Animation to a variable, e.g. anim, that exists until you have outputted the Animation using plt.show() or anim.save()

As plt.show() is called immediately after the call to FuncAnimation(), this is puzzling, but perhaps the following will help to ensure the Animation does not get deleted prematurely:

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import pandas as pd
from datetime import datetime, timedelta

def getPrices(i):
    return pd.DataFrame(index=[datetime.now()   timedelta(hours=i) for i in range(10)], data={'value1':range(10), 'value2':[(x   i) % 5 for x in range(10)]})

def doAnimation():
    fig=plt.figure()
    ax = fig.add_subplot(111)

    def animate(i):
        #data=prices(a,b,c)    #function that gives a DataFrame with 2 columns and index
        data = getPrices(i)

        plt.cla()
        ax.plot(data.index, data.value1)
        ax2 = ax.twinx()
        ax2.plot(data.index, data.value2)
        plt.gcf().autofmt_xdate()     
        plt.tight_layout()  
        return ax, ax2

    call = FuncAnimation(plt.gcf(), animate, 1000)  
    return call

callSave = doAnimation()
plt.show()
  • Related