I am trying to animate a GeoPandas map using dates (iterates through the day). I'm using MPL's FuncAnimation function and although there are no errors, there is no animation happening. Here is my code:
link = 'https://raw.githubusercontent.com/leakyMirror/map-of-europe/master/GeoJSON/europe.geojson'
europe = gpd.read_file(link)
europe_w_needed_countries = europe[europe.NAME.isin(train.country.unique())]
def create_gdf(date):
a = new_train.query(f"date == '{date}'").groupby('country').sum().reset_index()
b = europe_w_needed_countries[['LON', 'LAT', 'geometry']]
b.index = a.index
return gpd.GeoDataFrame(pd.concat([a,b], axis=1))
create_gdf('2017-01-01')
country num_sold LON LAT geometry
0 Belgium 3320 2.550 46.565 MULTIPOLYGON (((9.48583 42.61527, 9.49472 42.6...
1 France 2939 9.851 51.110 MULTIPOLYGON (((8.71026 47.69681, 8.67859 47.6...
2 Germany 3437 12.800 42.700 MULTIPOLYGON (((12.12778 47.00166, 12.13611 46...
3 Italy 2431 4.664 50.643 POLYGON ((4.30237 51.26318, 4.30968 51.26203, ...
4 Poland 1074 19.401 52.125 POLYGON ((18.85125 49.51736, 18.85222 49.52777...
5 Spain 2151 -3.649 40.227 MULTIPOLYGON (((-2.92528 35.26666, -2.93694 35...
For more context of this dataset, a
is supposed to represent the amount of books sold in European countries from 2017 to 2020. The data is aggregated. b
is a geojson-loaded Data Frame that displays the polygons of the countries. Both datasets are merged together, which is seen in the output code.
This is my code for the animation plot:
fig, ax = plt.subplots(figsize=(15,8))
date = '2017-01-01'
fontsize = 13
def animate(date):
gdf = create_gdf(date)
gdf.plot(ax=ax,
column='num_sold',
cmap='OrRd',
edgecolor='black',
legend=True,
legend_kwds={'label': 'Books Sold'})
ax.set_title('Books Sold From 1/1/2017 - 12/31/2020')
ax.set_axis_off()
ax.text(20, 45, 'Date:\n{}'.format(date), fontsize=fontsize, horizontalalignment='center')
for lon, lat, country in zip(gdf.LON, gdf.LAT, gdf.country):
ax.text(lon - 1.5, lat, country, fontsize=fontsize)
date = TimeDelta(1)
FuncAnimation(fig, update, interval=250, frames=new_train.index.unique())
As seen here, the map does not change. Also, I know the country names are in the wrong places, I'll change that later.
I don't know why this is happening, I followed other threads and articles and it never works.
CodePudding user response:
Animation of geopandas can be achieved with plot_polygon_collection(). I modified it to fit your code with
CodePudding user response:
Alternative approach, use plotly express Animation is built into the high level API
import geopandas as gpd
import pandas as pd
import numpy as np
import plotly.express as px
countries = ["Spain", "France", "Italy", "Belgium", "Germany", "Poland"]
europe = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres")).loc[
lambda d: d["name"].isin(countries)
]
df = pd.DataFrame(
{
"date": np.tile(pd.date_range("2020-08-01", periods=30), 6),
"country": np.repeat(countries, 30),
"num_sold": np.random.randint(1000, 5000, 180),
}
)
px.choropleth_mapbox(
df.assign(date_str=lambda d: d["date"].dt.strftime("%Y-%b-%d")),
geojson=europe.set_index("name")["geometry"].__geo_interface__,
locations="country",
color="num_sold",
color_continuous_scale='OrRd',
animation_frame="date_str",
).update_layout(
mapbox={
"style": "carto-positron",
"zoom": 2.5,
"center": {
"lat": europe.unary_union.centroid.y,
"lon": europe.unary_union.centroid.x,
},
},
coloraxis={"cmin": df["num_sold"].min(), "cmax": df["num_sold"].max()},
autosize=False,
width=600,
)
FYI I generated animated GIF using answer I provided here: animated GIF