I have a Dataframe with 6 rows of data and 4 columns. Is there any way to generate a gif scatterplot (y which are the 4 columns in different color versus x which are the index rows) plot in which in every frame of the gif, first data point of the Column 1 and its first respective row data is plotted in different color versus the shared x axis which are the indexes, at the same time, column 2, 3 and 4 first data points are plotted, and this goes progressively until the last 6th point is plotted for all of the columns? If a gif is not possible at all, is there any other way to generate at least movie so that I can include in my ppt slide? I appreciate any feedback you might have! The error I am getting is generating an empty plot and saying: TypeError: cannot unpack non-iterable AxesSubplot object. But I am not sure if this is preventing the result from the plotting.
This is a sample of my data and code effort:
import pandas as pd
import numpy as np
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import random
from itertools import count
from IPython import display
row_data = np.arange(0, 6)
column_X = np.random.rand(6,)
column_Y = np.random.rand(6,)
column_Z = np.random.rand(6,)
column_K = np.random.rand(6,)
my_df = pd.DataFrame()
my_df['column_X'] = column_X
my_df['column_Y'] = column_Y
my_df['column_Z'] = column_Z
my_df['column_K'] = column_K
my_df.index = row_data
my_df['index'] = row_data
def animate(j):
fig, ax = plt.subplot(sharex= True)
ax[1]=my_df['column_X', color = 'blue']
ax[2]=my_df['column_Y', color = 'red']
ax[3]=my_df['column_Z', color = 'brown']
ax[4]=my_df['column_K', color = 'green']
y=my_df['index']
x.append()
y.append()
plt.xlabel(color = 'blue')
plt.ylabel(color = 'red')
ax.set_ylabel("progressive sales through time")
ax.set_xlabel("progressive time")
plt.plot(x,y)
animation_1 = animation.FuncAnimation(plt.gcf(),animate,interval=1000)
plt.show()
# Inside Jupyter:
video_1 = animation_1.to_html5_video()
html_code_1 = display.HTML(video_1)
display.display(html_code_1)
plt.tight_layout()
plt.show()
CodePudding user response:
Good question! matplotlib animations can be tricky. I struggled a bit with this one, mainly because you want different colors for the different columns. You need 4 different Line2D objects to do this.
# VSCode notebook magic
%matplotlib widget
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
my_df = pd.DataFrame()
my_df["column_X"] = np.random.rand(6)
my_df["column_Y"] = np.random.rand(6)
my_df["column_Z"] = np.random.rand(6)
my_df["column_K"] = np.random.rand(6)
fig, ax = plt.subplots()
# four y-data lists, x-data is shared
xdata, y1, y2, y3, y4 = [], [], [], [], []
# four Line3D objects with different colors
graph1, = ax.plot([], [], 'ro-')
graph2, = ax.plot([], [], 'go-')
graph3, = ax.plot([], [], 'bo-')
graph4, = ax.plot([], [], 'ko-')
# set up the plot
plt.xlim(-1, 6)
plt.xlabel('Time')
plt.ylim(0, 1)
plt.ylabel('Price')
# animation function
def animate(i):
xdata.append(i)
y1.append(my_df.iloc[i,0])
y2.append(my_df.iloc[i,1])
y3.append(my_df.iloc[i,2])
y4.append(my_df.iloc[i,3])
graph1.set_data(xdata, y1)
graph2.set_data(xdata, y2)
graph3.set_data(xdata, y3)
graph4.set_data(xdata, y4)
return (graph1,graph2,graph3,graph4,)
anim = animation.FuncAnimation(fig, animate, frames=6, interval=500, blit=True)
anim.save('test.mp4')
#plt.show()
Here's the resulting .gif (converted from .mp4 using Adobe Express):