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