I am going to animate a time-series dataset which means there are two variables time(from day to day) and a changeable variable over a day. I used a code that has been written for a function to make animation. But it didn't work for me. I am a beginner at Python. So if there are other methods to make animation for time series datasets that you recommend I really appreciate it if you could comment and describe them to me. Mainly I have chosen this method because it was easy for me to follow.
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.animation import PillowWriter
fig = plt.figure()
l, = plt.plot([], [], 'k--')
plt.xlabel('Time')
plt.ylabel('DO')
plt.title('title')
metadata = dict(title='Movie', artist='codinglikemad')
writer = PillowWriter(fps=15, metadata=metadata)
xlist = []
ylist=[]
with writer.saving(fig, "DOtimeseries.gif", 100):
for xval in obsprof_ind.index.unique():
xlist.append(xval)
ylist.append(obsprof_ind[obsprof_ind.index== xval]['DO_obs'].mean())
#I also print xlist , ylist to ensure they work properly and they did : the export was [Timestamp('2012-06-01 00:00:00'), Timestamp('2012-06-02 00:00:00')] [7.157779211666667, 6.315558422666666]
l.set_data(xlist,ylist)
writer.grab_frame()
The original code was this:
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.animation import PillowWriter
fig = plt.figure()
l, = plt.plot([], [], 'k-')
plt.xlabel('xlabel')
plt.ylabel('ylabel')
plt.title('title')
plt.xlim(-5, 5)
plt.ylim(-5, 5)
def func(x):
return np.sin(x)*3
"""
xlist=np.linspace(-5,5,100)
ylist=func(xlist)
l.set_data(xlist,ylist)
plt.show()
"""
metadata = dict(title='Movie', artist='codinglikemad')
writer = PillowWriter(fps=15, metadata=metadata)
xlist = []
ylist=[]
with writer.saving(fig, "sinWave.gif", 100):
for xval in np.linspace(-5,5,100):
xlist.append(xval)
ylist.append(func(xval))
l.set_data(xlist,ylist)
writer.grab_frame() ```
CodePudding user response:
For animation i would use Plotly instead of trying to animate with GIF files and matplotlib. Saves a lot of time and much more interactive.
Check this : https://plotly.com/python/animations/
Example code :
import plotly.express as px
df = px.data.gapminder()
px.scatter(df, x="gdpPercap", y="lifeExp", animation_frame="year", animation_group="country",
size="pop", color="continent", hover_name="country",
log_x=True, size_max=55, range_x=[100,100000], range_y=[25,90])
Full Example
import plotly.graph_objects as go
import pandas as pd
url = "https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv"
dataset = pd.read_csv(url)
years = ["1952", "1962", "1967", "1972", "1977", "1982", "1987", "1992", "1997", "2002",
"2007"]
# make list of continents
continents = []
for continent in dataset["continent"]:
if continent not in continents:
continents.append(continent)
# make figure
fig_dict = {
"data": [],
"layout": {},
"frames": []
}
# fill in most of layout
fig_dict["layout"]["xaxis"] = {"range": [30, 85], "title": "Life Expectancy"}
fig_dict["layout"]["yaxis"] = {"title": "GDP per Capita", "type": "log"}
fig_dict["layout"]["hovermode"] = "closest"
fig_dict["layout"]["updatemenus"] = [
{
"buttons": [
{
"args": [None, {"frame": {"duration": 500, "redraw": False},
"fromcurrent": True, "transition": {"duration": 300,
"easing": "quadratic-in-out"}}],
"label": "Play",
"method": "animate"
},
{
"args": [[None], {"frame": {"duration": 0, "redraw": False},
"mode": "immediate",
"transition": {"duration": 0}}],
"label": "Pause",
"method": "animate"
}
],
"direction": "left",
"pad": {"r": 10, "t": 87},
"showactive": False,
"type": "buttons",
"x": 0.1,
"xanchor": "right",
"y": 0,
"yanchor": "top"
}
]
sliders_dict = {
"active": 0,
"yanchor": "top",
"xanchor": "left",
"currentvalue": {
"font": {"size": 20},
"prefix": "Year:",
"visible": True,
"xanchor": "right"
},
"transition": {"duration": 300, "easing": "cubic-in-out"},
"pad": {"b": 10, "t": 50},
"len": 0.9,
"x": 0.1,
"y": 0,
"steps": []
}
# make data
year = 1952
for continent in continents:
dataset_by_year = dataset[dataset["year"] == year]
dataset_by_year_and_cont = dataset_by_year[
dataset_by_year["continent"] == continent]
data_dict = {
"x": list(dataset_by_year_and_cont["lifeExp"]),
"y": list(dataset_by_year_and_cont["gdpPercap"]),
"mode": "markers",
"text": list(dataset_by_year_and_cont["country"]),
"marker": {
"sizemode": "area",
"sizeref": 200000,
"size": list(dataset_by_year_and_cont["pop"])
},
"name": continent
}
fig_dict["data"].append(data_dict)
# make frames
for year in years:
frame = {"data": [], "name": str(year)}
for continent in continents:
dataset_by_year = dataset[dataset["year"] == int(year)]
dataset_by_year_and_cont = dataset_by_year[
dataset_by_year["continent"] == continent]
data_dict = {
"x": list(dataset_by_year_and_cont["lifeExp"]),
"y": list(dataset_by_year_and_cont["gdpPercap"]),
"mode": "markers",
"text": list(dataset_by_year_and_cont["country"]),
"marker": {
"sizemode": "area",
"sizeref": 200000,
"size": list(dataset_by_year_and_cont["pop"])
},
"name": continent
}
frame["data"].append(data_dict)
fig_dict["frames"].append(frame)
slider_step = {"args": [
[year],
{"frame": {"duration": 300, "redraw": False},
"mode": "immediate",
"transition": {"duration": 300}}
],
"label": year,
"method": "animate"}
sliders_dict["steps"].append(slider_step)
fig_dict["layout"]["sliders"] = [sliders_dict]
fig = go.Figure(fig_dict)
fig.show()
CodePudding user response:
I found out I should have defined the x and y axes limitation.