Issue
I am trying to generate a continously generated plot in matplotlib. The problem that I am facing is related to the labelling on the right y-axis. The range that shows is my desired, however there is also an additional set off labels (0, 0.2, ... 1,0).
def doAnimation():
fig, ax = plt.subplots()
def animate(i):
data=prices(a,b,c) #this gives a DataFrame with 2 columns (value 1 and 2)
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()
Any ideas how can I get rid of the set: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0?
Solution
plt.cla
clears the current axes. The first time you call plt.cla
, the current axes are ax
(ax2
doesn't exist yet). Clearing these axes resets both the x and y range of ax
to (0,1). However, on line 8, you plot to ax
, and both ranges are appropriately adjusted.
On line 9, you create a new set of axes and call them ax2
. When you leave the animate
function, the name ax2
will go out of scope, but the axes object to which it refers will persist. These axes are now the current axes.
The second time you call animate, plt.cla
clears those axes, resetting the x and y range to (0,1). Then, on line 9, you create a new set of axes and call them ax2
. These axes are not the same axes as before! ax2
in fact refers to a third set of axes, which will be cleared the next time you call plt.cla
. Each new call to animate makes a new set of axes. The offending axes labels appear to be bolded; in fact, they have been drawn a thousand times.
The simplest (fewest changes) fix would be to move ax2 = ax.twinx()
outside of animate
, and replace plt.cla
with separate calls to ax.cla
and ax2.cla
.
I think a better approach would be to create the lines outside of animate
, and modify their data within animate
. While we're at it, let's replace those references to plt.gcf()
with references to fig
, and set tight_layout
via an argument to plt.subplots
.
Putting said changes together, we get,
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import pandas as pd
import numpy as np
def dummy_prices():
samples = 101
xs = np.linspace(0, 10, samples)
ys = np.random.randn(samples)
zs = np.random.randn(samples) * 10 + 50
return pd.DataFrame.from_records({'value1': ys, 'value2': zs}, index=xs)
def doAnimation():
fig, ax = plt.subplots(1, 1, tight_layout=True)
fig.autofmt_xdate()
ax2 = ax.twinx()
data = dummy_prices()
line = ax.plot(data.index, data.value1)[0]
line2 = ax2.plot(data.index, data.value2, 'r')[0]
def animate(i):
data = dummy_prices()
line.set_data(data.index, data.value1)
line2.set_data(data.index, data.value2)
return line, line2
animator = FuncAnimation(fig, animate, frames=10)
return animator
def main():
animator = doAnimation()
animator.save('animation.gif')
if __name__ == '__main__':
main()
where animation.gif
should look something like,
Answered By - fanjie
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.