mapclassify icon indicating copy to clipboard operation
mapclassify copied to clipboard

`plot` doesn't work for pooled classifications

Open darribas opened this issue 4 years ago • 2 comments

The plot utility function for classification objects does not seem to work for pooled classifications. This might be expected behaviour or not supported functionality but just in case.

Reproducible error:

from pysal.lib import examples
import mapclassify
import geopandas


mx_ex = examples.load_example('mexico')
mx = geopandas.read_file(mx_ex.get_file_list()[0])

years = ['PCGDP1940', 'PCGDP1960', 'PCGDP1980', 'PCGDP2000']
pooled = mapclassify.Pooled(mx[years])

for i, y in enumerate(years):
    classi = pooled.col_classifiers[i]
    classi.plot(mx)

which on the gds_env:6.1 returns:

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/opt/conda/lib/python3.8/site-packages/geopandas/plotting.py in _mapclassify_choro(values, scheme, **classification_kwds)
   1010     try:
-> 1011         scheme_class = schemes[scheme]
   1012     except KeyError:

KeyError: 'pooled quantiles'

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
/opt/conda/lib/python3.8/site-packages/geopandas/plotting.py in _mapclassify_choro(values, scheme, **classification_kwds)
   1014         try:
-> 1015             scheme_class = schemes[scheme]
   1016         except KeyError:

KeyError: 'pooled quantiles'

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
<ipython-input-20-f10e01e9c42e> in <module>
     12 for i, y in enumerate(years):
     13     classi = pooled.col_classifiers[i]
---> 14     classi.plot(mx)

/opt/conda/lib/python3.8/site-packages/mapclassify/classifiers.py in plot(self, gdf, border_color, border_width, title, legend, cmap, axis_on, legend_kwds, file_name, dpi, ax)
   2336             fmt = legend_kwds.pop("fmt")
   2337 
-> 2338         ax = gdf.assign(_cl=self.y).plot(
   2339             column="_cl",
   2340             ax=ax,

/opt/conda/lib/python3.8/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

/opt/conda/lib/python3.8/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)
    750             classification_kwds["k"] = k
    751 
--> 752         binning = _mapclassify_choro(values[~nan_idx], scheme, **classification_kwds)
    753         # set categorical to True for creating the legend
    754         categorical = True

/opt/conda/lib/python3.8/site-packages/geopandas/plotting.py in _mapclassify_choro(values, scheme, **classification_kwds)
   1015             scheme_class = schemes[scheme]
   1016         except KeyError:
-> 1017             raise ValueError(
   1018                 "Invalid scheme. Scheme must be in the set: %r" % schemes.keys()
   1019             )

ValueError: Invalid scheme. Scheme must be in the set: dict_keys(['boxplot', 'equalinterval', 'fisherjenks', 'fisherjenkssampled', 'headtailbreaks', 'jenkscaspall', 'jenkscaspallforced', 'jenkscaspallsampled', 'maxp', 'maximumbreaks', 'naturalbreaks', 'quantiles', 'percentiles', 'stdmean', 'userdefined'])

darribas avatar Jul 23 '21 15:07 darribas

This is because classi in classi = pooled.col_classifiers[i] is an instance of a classifier - in other words, it has already been fit.

To see this, try to change the loop as follows:

from pysal.lib import examples
import mapclassify
import geopandas


mx_ex = examples.load_example('mexico')
mx = geopandas.read_file(mx_ex.get_file_list()[0])

years = ['PCGDP1940', 'PCGDP1960', 'PCGDP1980', 'PCGDP2000']
pooled = mapclassify.Pooled(mx[years])

for i, y in enumerate(years):
    classi = pooled.col_classifiers[i]
    label = f'pooled-{y}'
    mx[label] = classi.yb
    mx.plot(column=label, categorical=True, legend=True)

sjsrey avatar Feb 03 '22 03:02 sjsrey

I think this is no longer an issue given the book chapter?

sjsrey avatar Feb 03 '22 04:02 sjsrey