JackMcKew / pandas_alive

Create stunning, animated visualisations with Pandas & Matplotlib as easy as calling `df.plot_animated()`
MIT License
582 stars 100 forks source link

Unable to customise period label position in `geopandas` animations #33

Open robbibt opened 3 years ago

robbibt commented 3 years ago

Describe the bug

1 adds x_period_label_location, y_period_label_location and append_period_to_title params to .plot_animated to allow users to customise the position of the period label. However, this does not appear to work for animations based on geopandas.GeoDataFrame objects.

To Reproduce

import geopandas
import pandas_alive
import contextily

gdf = geopandas.read_file('data/nsw-covid19-cases-by-postcode.gpkg').iloc[:,[0, 1, -2, -1]]
gdf.index = gdf.postcode
gdf = gdf.drop('postcode',axis=1)

map_chart = gdf.plot_animated(filename='example-geo-point-chart.gif',
                              append_period_to_title=True)

map_chart2 = gdf.plot_animated(filename='example-geo-point-chart.gif',
                              x_period_label_location=0,
                              y_period_label_location=0)                              

But I receive the following error:

/env/lib/python3.6/site-packages/geopandas/geodataframe.py:577: RuntimeWarning: Sequential read of iterator was interrupted. Resetting iterator. This can negatively impact the performance.
  for feature in features_lst:
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-21-0a82dea1cbbe> in <module>
      9 
     10 map_chart = gdf.plot_animated(filename='example-geo-point-chart.gif',
---> 11                               append_period_to_title=True)  #,basemap_format={'source':contextily.providers.Stamen.Terrain})

/env/lib/python3.6/site-packages/pandas_alive/geoplotting.py in geoplot(input_df, filename, kind, interpolate_period, steps_per_period, period_length, period_fmt, figsize, title, fig, cmap, tick_label_size, period_label, period_summary_func, fixed_max, dpi, writer, enable_progress_bar, basemap_format, enable_markersize, scale_markersize, **kwargs)
     76     )
     77     if filename:
---> 78         map_chart.save(verify_filename(filename))
     79     return map_chart

/env/lib/python3.6/site-packages/pandas_alive/_base_chart.py in save(self, filename)
    605                     frames = []
    606                     for i in range(0, num_frames):
--> 607                         self.anim_func(i)
    608                         buffer = io.BytesIO()
    609                         self.fig.savefig(buffer, format="png")

/env/lib/python3.6/site-packages/pandas_alive/geocharts.py in anim_func(self, i)
    211         self.ax.clear()
    212         self.ax.set_axis_off()
--> 213         self.plot_geo_data(i, self.df)
    214         if self.period_fmt:
    215             self.show_period(i)

/env/lib/python3.6/site-packages/pandas_alive/geocharts.py in plot_geo_data(self, i, gdf)
    180             # cmap='Blues',
    181             cmap=self.cmap,
--> 182             **self.kwargs,
    183         )
    184 

/env/lib/python3.6/site-packages/geopandas/plotting.py in __call__(self, *args, **kwargs)
    923             kind = kwargs.pop("kind", "geo")
    924             if kind == "geo":
--> 925                 return plot_dataframe(data, *args, **kwargs)
    926             if kind in self._pandas_kinds:
    927                 # Access pandas plots

/env/lib/python3.6/site-packages/geopandas/plotting.py in plot_dataframe(df, column, cmap, color, ax, cax, categorical, legend, scheme, k, vmin, vmax, markersize, figsize, legend_kwds, categories, classification_kwds, missing_kwds, aspect, **style_kwds)
    832             markersize=markersize,
    833             cmap=cmap,
--> 834             **style_kwds,
    835         )
    836 

/env/lib/python3.6/site-packages/geopandas/plotting.py in _plot_point_collection(ax, geoms, values, color, cmap, vmin, vmax, marker, markersize, **kwargs)
    301 
    302     if "norm" not in kwargs:
--> 303         collection = ax.scatter(x, y, vmin=vmin, vmax=vmax, cmap=cmap, **kwargs)
    304     else:
    305         collection = ax.scatter(x, y, cmap=cmap, **kwargs)

/env/lib/python3.6/site-packages/matplotlib/__init__.py in inner(ax, data, *args, **kwargs)
   1563     def inner(ax, *args, data=None, **kwargs):
   1564         if data is None:
-> 1565             return func(ax, *map(sanitize_sequence, args), **kwargs)
   1566 
   1567         bound = new_sig.bind(ax, *args, **kwargs)

/env/lib/python3.6/site-packages/matplotlib/cbook/deprecation.py in wrapper(*args, **kwargs)
    356                 f"%(removal)s.  If any parameter follows {name!r}, they "
    357                 f"should be pass as keyword, not positionally.")
--> 358         return func(*args, **kwargs)
    359 
    360     return wrapper

/env/lib/python3.6/site-packages/matplotlib/axes/_axes.py in scatter(self, x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, verts, edgecolors, plotnonfinite, **kwargs)
   4430                 )
   4431         collection.set_transform(mtransforms.IdentityTransform())
-> 4432         collection.update(kwargs)
   4433 
   4434         if colors is None:

/env/lib/python3.6/site-packages/matplotlib/artist.py in update(self, props)
   1004 
   1005         with cbook._setattr_cm(self, eventson=False):
-> 1006             ret = [_update_property(self, k, v) for k, v in props.items()]
   1007 
   1008         if len(ret):

/env/lib/python3.6/site-packages/matplotlib/artist.py in <listcomp>(.0)
   1004 
   1005         with cbook._setattr_cm(self, eventson=False):
-> 1006             ret = [_update_property(self, k, v) for k, v in props.items()]
   1007 
   1008         if len(ret):

/env/lib/python3.6/site-packages/matplotlib/artist.py in _update_property(self, k, v)
   1000                 if not callable(func):
   1001                     raise AttributeError('{!r} object has no property {!r}'
-> 1002                                          .format(type(self).__name__, k))
   1003                 return func(v)
   1004 

AttributeError: 'PathCollection' object has no property 'append_period_to_title'

Expected behavior I would expect to be able to use the x_period_label_location, y_period_label_location and append_period_to_title params in .plot_animated, regardless of whether I provide pandas or geopandas data.

Additional context pandas_alive version '0.2.4'