VIS: updated plotting defaults (#510)

* remove hardcoded defaults

* use uniform color by default

* for categorical data use default cmap tab10 instead of Set1

* forgot to remove hardcoded markersize

* remove no longer used gencolor function

* update MultiPolygons test

* fix some tests + mixed geom case with cmap

* enable more tests

* fix for matplotlib 1.4.3

* skip one for 1.4.3

* fix some collection tests

* small updates to docstring

* undo take squaring of the markersize
This commit is contained in:
Joris Van den Bossche
2017-08-27 10:19:08 -07:00
committed by James McBride
parent c6cf3b2bba
commit 4ed906ece6
2 changed files with 180 additions and 196 deletions
+88 -100
View File
@@ -1,9 +1,9 @@
from __future__ import print_function
from distutils.version import LooseVersion
import warnings
import numpy as np
from six import next
def _flatten_multi_geoms(geoms, colors=None):
@@ -43,9 +43,8 @@ def _flatten_multi_geoms(geoms, colors=None):
return components, component_colors
def plot_polygon_collection(ax, geoms, values=None, linewidth=1.0,
edgecolor='black', alpha=0.5,
vmin=None, vmax=None, cmap=None, **kwargs):
def plot_polygon_collection(ax, geoms, values=None, color=None,
cmap=None, vmin=None, vmax=None, **kwargs):
"""
Plots a collection of Polygon and MultiPolygon geometries to `ax`
@@ -90,9 +89,12 @@ def plot_polygon_collection(ax, geoms, values=None, linewidth=1.0,
if 'markersize' in kwargs:
del kwargs['markersize']
# color=None overwrites specified facecolor/edgecolor with default color
if color is not None:
kwargs['color'] = color
collection = PatchCollection([PolygonPatch(poly) for poly in geoms],
linewidth=linewidth, edgecolor=edgecolor,
alpha=alpha, **kwargs)
**kwargs)
if values is not None:
collection.set_array(np.asarray(values))
@@ -105,8 +107,7 @@ def plot_polygon_collection(ax, geoms, values=None, linewidth=1.0,
def plot_linestring_collection(ax, geoms, values=None, color=None,
vmin=None, vmax=None, cmap=None,
linewidth=1.0, **kwargs):
cmap=None, vmin=None, vmax=None, **kwargs):
"""
Plots a collection of LineString and MultiLineString geometries to `ax`
@@ -147,7 +148,7 @@ def plot_linestring_collection(ax, geoms, values=None, color=None,
kwargs['color'] = color
segments = [np.array(linestring)[:, :2] for linestring in geoms]
collection = LineCollection(segments, linewidth=linewidth, **kwargs)
collection = LineCollection(segments, **kwargs)
if values is not None:
collection.set_array(np.asarray(values))
@@ -160,8 +161,8 @@ def plot_linestring_collection(ax, geoms, values=None, color=None,
def plot_point_collection(ax, geoms, values=None, color=None,
vmin=None, vmax=None, cmap=None,
marker='o', markersize=2, **kwargs):
cmap=None, vmin=None, vmax=None,
marker='o', markersize=None, **kwargs):
"""
Plots a collection of Point geometries to `ax`
@@ -177,6 +178,11 @@ def plot_point_collection(ax, geoms, values=None, color=None,
Values mapped to colors using vmin, vmax, and cmap.
Cannot be specified together with `color`.
markersize : scalar or array-like, optional
Size of the markers. Note that under the hood ``scatter`` is
used, so the specified value will be proportional to the
area of the marker (size in points^2).
Returns
-------
collection : matplotlib.collections.Collection that was plotted
@@ -187,34 +193,18 @@ def plot_point_collection(ax, geoms, values=None, color=None,
x = geoms.x.values
y = geoms.y.values
collection = ax.scatter(x, y, s=markersize, c=values, color=color,
vmin=vmin, vmax=vmax, cmap=cmap,
# matplotlib 1.4 does not support c=None, and < 2.0 does not support s=None
if values is not None:
kwargs['c'] = values
if markersize is not None:
kwargs['s'] = markersize
collection = ax.scatter(x, y, color=color, vmin=vmin, vmax=vmax, cmap=cmap,
marker=marker, **kwargs)
return collection
def _gencolor(N, colormap='Set1'):
"""
Color generator intended to work with one of the ColorBrewer
qualitative color scales.
Suggested values of colormap are the following:
Accent, Dark2, Paired, Pastel1, Pastel2, Set1, Set2, Set3
(although any matplotlib colormap will work).
"""
from matplotlib import cm
# don't use more than 9 discrete colors
n_colors = min(N, 9)
cmap = cm.get_cmap(colormap, n_colors)
colors = cmap(range(n_colors))
for i in range(N):
yield colors[i % n_colors]
def plot_series(s, cmap='Set1', color=None, ax=None, linewidth=1.0,
figsize=None, **color_kwds):
def plot_series(s, cmap=None, color=None, ax=None, figsize=None, **style_kwds):
"""
Plot a GeoSeries.
@@ -228,13 +218,13 @@ def plot_series(s, cmap='Set1', color=None, ax=None, linewidth=1.0,
MultiPolygon, LineString, MultiLineString and Point
geometries can be plotted.
cmap : str (default 'Set1')
cmap : str (default None)
The name of a colormap recognized by matplotlib. Any
colormap will work, but categorical colormaps are
generally recommended. Examples of useful discrete
colormaps include:
Accent, Dark2, Paired, Pastel1, Pastel2, Set1, Set2, Set3
tab10, tab20, Accent, Dark2, Paired, Pastel1, Set1, Set2
color : str (default None)
If specified, all objects will be colored uniformly.
@@ -242,42 +232,42 @@ def plot_series(s, cmap='Set1', color=None, ax=None, linewidth=1.0,
ax : matplotlib.pyplot.Artist (default None)
axes on which to draw the plot
linewidth : float (default 1.0)
Line width for geometries.
figsize : pair of floats (default None)
Size of the resulting matplotlib.figure.Figure. If the argument
ax is given explicitly, figsize is ignored.
**color_kwds : dict
Color options to be passed on to the actual plot function
**style_kwds : dict
Color options to be passed on to the actual plot function, such
as ``edgecolor``, ``facecolor``, ``linewidth``, ``markersize``,
``alpha``.
Returns
-------
matplotlib axes instance
"""
if 'colormap' in color_kwds:
if 'colormap' in style_kwds:
warnings.warn("'colormap' is deprecated, please use 'cmap' instead "
"(for consistency with matplotlib)", FutureWarning)
cmap = color_kwds.pop('colormap')
if 'axes' in color_kwds:
cmap = style_kwds.pop('colormap')
if 'axes' in style_kwds:
warnings.warn("'axes' is deprecated, please use 'ax' instead "
"(for consistency with pandas)", FutureWarning)
ax = color_kwds.pop('axes')
ax = style_kwds.pop('axes')
import matplotlib.pyplot as plt
if ax is None:
fig, ax = plt.subplots(figsize=figsize)
ax.set_aspect('equal')
# if no color specified, create range of colors based on cmap
num_geoms = len(s.index)
col_seq = False
if color is None:
color_generator = _gencolor(len(s), colormap=cmap)
color = np.array([next(color_generator) for _ in range(num_geoms)])
col_seq = True
# if cmap is specified, create range of colors based on cmap
values = None
if cmap is not None:
values = np.arange(len(s))
if hasattr(cmap, 'N'):
values = values % cmap.N
style_kwds['vmin'] = style_kwds.get('vmin', values.min())
style_kwds['vmax'] = style_kwds.get('vmax', values.max())
geom_types = s.geometry.type
poly_idx = np.asarray((geom_types == 'Polygon')
@@ -292,43 +282,40 @@ def plot_series(s, cmap='Set1', color=None, ax=None, linewidth=1.0,
if not polys.empty:
# color overrides both face and edgecolor. As we want people to be
# able to use edgecolor as well, pass color to facecolor
facecolor = color_kwds.pop('facecolor', None)
if col_seq:
if not facecolor:
facecolor = color[poly_idx] if col_seq else color
else:
facecolor = style_kwds.pop('facecolor', None)
if color is not None:
facecolor = color
plot_polygon_collection(ax, polys, facecolor=facecolor,
linewidth=linewidth, **color_kwds)
values_ = values[poly_idx] if cmap else None
plot_polygon_collection(ax, polys, values_, facecolor=facecolor,
cmap=cmap, **style_kwds)
# plot all LineStrings and MultiLineString components in same collection
lines = s.geometry[line_idx]
if not lines.empty:
color_ = color[line_idx] if col_seq else color
plot_linestring_collection(ax, lines, color=color_,
linewidth=linewidth, **color_kwds)
values_ = values[line_idx] if cmap else None
plot_linestring_collection(ax, lines, values_, color=color, cmap=cmap,
**style_kwds)
# plot all Points in the same collection
points = s.geometry[point_idx]
if not points.empty:
color_ = color[point_idx] if col_seq else color
plot_point_collection(ax, points, color=color_, **color_kwds)
values_ = values[point_idx] if cmap else None
plot_point_collection(ax, points, values_, color=color, cmap=cmap,
**style_kwds)
plt.draw()
return ax
def plot_dataframe(df, column=None, cmap=None, color=None, linewidth=1.0,
categorical=False, legend=False, ax=None,
scheme=None, k=5, vmin=None, vmax=None, figsize=None,
**color_kwds):
def plot_dataframe(df, column=None, cmap=None, color=None, ax=None,
categorical=False, legend=False, scheme=None, k=5,
vmin=None, vmax=None, figsize=None, **style_kwds):
"""
Plot a GeoDataFrame.
Generate a plot of a GeoDataFrame with matplotlib. If a
column is specified, the plot coloring will be based on values
in that column. Otherwise, a categorical plot of the
geometries in the `geometry` column will be generated.
in that column.
Parameters
----------
@@ -341,39 +328,37 @@ def plot_dataframe(df, column=None, cmap=None, color=None, linewidth=1.0,
column : str (default None)
The name of the column to be plotted. Ignored if `color` is also set.
cmap : str (default None)
The name of a colormap recognized by matplotlib.
categorical : bool (default False)
If False, cmap will reflect numerical values of the
column being plotted. For non-numerical columns (or if
column=None), this will be set to True.
cmap : str (default 'Set1')
The name of a colormap recognized by matplotlib.
column being plotted. For non-numerical columns, this
will be set to True.
color : str (default None)
If specified, all objects will be colored uniformly.
linewidth : float (default 1.0)
Line width for geometries.
legend : bool (default False)
Plot a legend. Ignored if no `column` is given, or if `color` is given.
ax : matplotlib.pyplot.Artist (default None)
axes on which to draw the plot
scheme : pysal.esda.mapclassify.Map_Classifier
Choropleth classification schemes (requires PySAL)
scheme : str (default None)
Name of a choropleth classification scheme (requires PySAL).
A pysal.esda.mapclassify.Map_Classifier object will be used
under the hood. Supported schemes: 'Equal_interval', 'Quantiles',
'Fisher_Jenks'
k : int (default 5)
Number of classes (ignored if scheme is None)
vmin : None or float (default None)
Minimum value of cmap. If None, the minimum data value
in the column to be plotted is used.
vmax : None or float (default None)
Maximum value of cmap. If None, the maximum data value
in the column to be plotted is used.
@@ -381,33 +366,35 @@ def plot_dataframe(df, column=None, cmap=None, color=None, linewidth=1.0,
Size of the resulting matplotlib.figure.Figure. If the argument
axes is given explicitly, figsize is ignored.
**color_kwds : dict
Color options to be passed on to the actual plot function
**style_kwds : dict
Color options to be passed on to the actual plot function, such
as ``edgecolor``, ``facecolor``, ``linewidth``, ``markersize``,
``alpha``.
Returns
-------
matplotlib axes instance
"""
if 'colormap' in color_kwds:
if 'colormap' in style_kwds:
warnings.warn("'colormap' is deprecated, please use 'cmap' instead "
"(for consistency with matplotlib)", FutureWarning)
cmap = color_kwds.pop('colormap')
if 'axes' in color_kwds:
cmap = style_kwds.pop('colormap')
if 'axes' in style_kwds:
warnings.warn("'axes' is deprecated, please use 'ax' instead "
"(for consistency with pandas)", FutureWarning)
ax = color_kwds.pop('axes')
ax = style_kwds.pop('axes')
if column and color:
warnings.warn("Only specify one of 'column' or 'color'. Using "
"'color'.", UserWarning)
column = None
import matplotlib
import matplotlib.pyplot as plt
if column is None:
return plot_series(df.geometry, cmap=cmap, color=color,
ax=ax, linewidth=linewidth, figsize=figsize,
**color_kwds)
return plot_series(df.geometry, cmap=cmap, color=color, ax=ax,
figsize=figsize, **style_kwds)
if df[column].dtype is np.dtype('O'):
categorical = True
@@ -415,7 +402,10 @@ def plot_dataframe(df, column=None, cmap=None, color=None, linewidth=1.0,
# Define `values` as a Series
if categorical:
if cmap is None:
cmap = 'Set1'
if LooseVersion(matplotlib.__version__) >= '2.0':
cmap = 'tab10'
else:
cmap = 'Set1'
categories = list(set(df[column].values))
categories.sort()
valuemap = dict([(k, v) for (v, k) in enumerate(categories)])
@@ -449,21 +439,19 @@ def plot_dataframe(df, column=None, cmap=None, color=None, linewidth=1.0,
polys = df.geometry[poly_idx]
if not polys.empty:
plot_polygon_collection(ax, polys, values[poly_idx],
vmin=mn, vmax=mx, cmap=cmap,
linewidth=linewidth, **color_kwds)
vmin=mn, vmax=mx, cmap=cmap, **style_kwds)
# plot all LineStrings and MultiLineString components in same collection
lines = df.geometry[line_idx]
if not lines.empty:
plot_linestring_collection(ax, lines, values[line_idx],
vmin=mn, vmax=mx, cmap=cmap,
linewidth=linewidth, **color_kwds)
vmin=mn, vmax=mx, cmap=cmap, **style_kwds)
# plot all Points in the same collection
points = df.geometry[point_idx]
if not points.empty:
plot_point_collection(ax, points, values[point_idx],
vmin=mn, vmax=mx, cmap=cmap, **color_kwds)
vmin=mn, vmax=mx, cmap=cmap, **style_kwds)
if legend and not color:
from matplotlib.lines import Line2D
@@ -477,7 +465,7 @@ def plot_dataframe(df, column=None, cmap=None, color=None, linewidth=1.0,
for value, cat in enumerate(categories):
patches.append(
Line2D([0], [0], linestyle="none", marker="o",
alpha=color_kwds.get('alpha', 0.5), markersize=10,
alpha=style_kwds.get('alpha', 1), markersize=10,
markerfacecolor=n_cmap.to_rgba(value)))
ax.legend(patches, categories, numpoints=1, loc='best')
else:
+92 -96
View File
@@ -32,10 +32,6 @@ except KeyError:
class TestPointPlotting:
def setup_method(self):
# scatterplot does not yet accept list of colors in matplotlib 1.4.3
# if we change the default to uniform, this might work again
pytest.importorskip('matplotlib', '1.5.0')
self.N = 10
self.points = GeoSeries(Point(i, i) for i in range(self.N))
values = np.arange(self.N)
@@ -51,45 +47,50 @@ class TestPointPlotting:
def test_default_colors(self):
# # without specifying values -> max 9 different colors
# # without specifying values -> uniform color
# GeoSeries
ax = self.points.plot()
cmap = plt.get_cmap('Set1', 9)
expected_colors = cmap(list(range(9))*2)
_check_colors(self.N, ax.collections[0].get_facecolors(), expected_colors)
_check_colors(self.N, ax.collections[0].get_facecolors(),
[MPL_DFT_COLOR] * self.N)
# GeoDataFrame -> uses 'jet' instead of 'Set1'
# GeoDataFrame
ax = self.df.plot()
cmap = plt.get_cmap(lut=9)
expected_colors = cmap(list(range(9))*2)
_check_colors(self.N, ax.collections[0].get_facecolors(), expected_colors)
_check_colors(self.N, ax.collections[0].get_facecolors(),
[MPL_DFT_COLOR] * self.N)
# # with specifying values -> different colors for all 10 values
ax = self.df.plot(column='values')
cmap = plt.get_cmap()
expected_colors = cmap(np.arange(self.N)/(self.N-1))
_check_colors(self.N, ax.collections[0].get_facecolors(), expected_colors)
_check_colors(self.N, ax.collections[0].get_facecolors(),
expected_colors)
def test_colormap(self):
# # without specifying values -> max 9 different colors
# without specifying values but cmap specified -> no uniform color
# but different colors for all points
# GeoSeries
ax = self.points.plot(cmap='RdYlGn')
cmap = plt.get_cmap('RdYlGn', 9)
expected_colors = cmap(list(range(9))*2)
_check_colors(self.N, ax.collections[0].get_facecolors(), expected_colors)
cmap = plt.get_cmap('RdYlGn')
exp_colors = cmap(np.arange(self.N) / (self.N - 1))
_check_colors(self.N, ax.collections[0].get_facecolors(), exp_colors)
# GeoDataFrame -> same as GeoSeries in this case
ax = self.df.plot(cmap='RdYlGn')
_check_colors(self.N, ax.collections[0].get_facecolors(), expected_colors)
_check_colors(self.N, ax.collections[0].get_facecolors(), exp_colors)
# # with specifying values -> different colors for all 10 values
ax = self.df.plot(column='values', cmap='RdYlGn')
cmap = plt.get_cmap('RdYlGn')
expected_colors = cmap(np.arange(self.N)/(self.N-1))
_check_colors(self.N, ax.collections[0].get_facecolors(), expected_colors)
_check_colors(self.N, ax.collections[0].get_facecolors(), exp_colors)
# when using a cmap with specified lut -> limited number of different
# colors
ax = self.points.plot(cmap=plt.get_cmap('Set1', lut=5))
cmap = plt.get_cmap('Set1', lut=5)
exp_colors = cmap(list(range(5))*3)
_check_colors(self.N, ax.collections[0].get_facecolors(), exp_colors)
def test_single_color(self):
@@ -106,7 +107,6 @@ class TestPointPlotting:
def test_style_kwargs(self):
# markersize
ax = self.points.plot(markersize=10)
assert ax.collections[0].get_sizes() == [10]
@@ -150,10 +150,6 @@ class TestPointPlotting:
class TestPointZPlotting:
def setup_method(self):
# scatterplot does not yet accept list of colors in matplotlib 1.4.3
# if we change the default to uniform, this might work again
pytest.importorskip('matplotlib', '1.5.0')
self.N = 10
self.points = GeoSeries(Point(i, i, i) for i in range(self.N))
values = np.arange(self.N)
@@ -189,20 +185,20 @@ class TestLineStringPlotting:
def test_style_kwargs(self):
# linestyle
# linestyle (style patterns depend on linewidth, therefore pin to 1)
linestyle = 'dashed'
ax = self.lines.plot(linestyle=linestyle)
ax = self.lines.plot(linestyle=linestyle, linewidth=1)
exp_ls = _style_to_linestring_onoffseq(linestyle)
for ls in ax.collections[0].get_linestyles():
assert ls[0] == exp_ls[0]
assert tuple(ls[1]) == exp_ls[1]
ax = self.df.plot(linestyle=linestyle)
ax = self.df.plot(linestyle=linestyle, linewidth=1)
for ls in ax.collections[0].get_linestyles():
assert ls[0] == exp_ls[0]
assert tuple(ls[1]) == exp_ls[1]
ax = self.df.plot(column='values', linestyle=linestyle)
ax = self.df.plot(column='values', linestyle=linestyle, linewidth=1)
for ls in ax.collections[0].get_linestyles():
assert ls[0] == exp_ls[0]
assert tuple(ls[1]) == exp_ls[1]
@@ -225,21 +221,20 @@ class TestPolygonPlotting:
def test_single_color(self):
ax = self.polys.plot(color='green')
_check_colors(2, ax.collections[0].get_facecolors(), ['green']*2, alpha=0.5)
_check_colors(2, ax.collections[0].get_facecolors(), ['green']*2)
# color only sets facecolor
_check_colors(2, ax.collections[0].get_edgecolors(), ['k'] * 2, alpha=0.5)
_check_colors(2, ax.collections[0].get_edgecolors(), ['k'] * 2)
ax = self.df.plot(color='green')
_check_colors(2, ax.collections[0].get_facecolors(), ['green']*2, alpha=0.5)
_check_colors(2, ax.collections[0].get_edgecolors(), ['k'] * 2, alpha=0.5)
_check_colors(2, ax.collections[0].get_facecolors(), ['green']*2)
_check_colors(2, ax.collections[0].get_edgecolors(), ['k'] * 2)
with warnings.catch_warnings(record=True) as _: # don't print warning
# 'color' overrides 'values'
ax = self.df.plot(column='values', color='green')
_check_colors(2, ax.collections[0].get_facecolors(), ['green']*2, alpha=0.5)
_check_colors(2, ax.collections[0].get_facecolors(), ['green']*2)
def test_vmin_vmax(self):
# when vmin == vmax, all polygons should be the same color
# non-categorical
@@ -256,7 +251,7 @@ class TestPolygonPlotting:
# facecolor overrides default cmap when color is not set
ax = self.polys.plot(facecolor='k')
_check_colors(2, ax.collections[0].get_facecolors(), ['k']*2, alpha=0.5)
_check_colors(2, ax.collections[0].get_facecolors(), ['k']*2)
# facecolor overrides more general-purpose color when both are set
ax = self.polys.plot(color='red', facecolor='k')
@@ -265,30 +260,30 @@ class TestPolygonPlotting:
# edgecolor
ax = self.polys.plot(edgecolor='red')
np.testing.assert_array_equal([(1, 0, 0, 0.5)],
np.testing.assert_array_equal([(1, 0, 0, 1)],
ax.collections[0].get_edgecolors())
ax = self.df.plot('values', edgecolor='red')
np.testing.assert_array_equal([(1, 0, 0, 0.5)],
np.testing.assert_array_equal([(1, 0, 0, 1)],
ax.collections[0].get_edgecolors())
# alpha sets both edge and face
ax = self.polys.plot(facecolor='g', edgecolor='r', alpha=0.4)
_check_colors(2, ax.collections[0].get_facecolors(), ['g'] * 2, alpha=0.4)
_check_colors(2, ax.collections[0].get_edgecolors(), ['r'] * 2, alpha=0.4)
def test_multipolygons(self):
# MultiPolygons
ax = self.df2.plot()
assert len(ax.collections[0].get_paths()) == 4
_check_colors(4, ax.collections[0].get_facecolors(), [MPL_DFT_COLOR]*4)
ax = self.df2.plot('values')
cmap = plt.get_cmap(lut=2)
# colors are repeated for all components within a MultiPolygon
expected_colors = [cmap(0), cmap(0), cmap(1), cmap(1)]
# TODO multipolygons don't work yet when values are not specified
# values are flattended, but color not yet (can fix, but we are
# thinking to use uniform coloring by default, which would also fix
# this)
# _check_colors(4, ax.collections[0], expected_colors, alpha=0.5)
ax = self.df2.plot('values')
# specifying values -> same as without values in this case.
_check_colors(4, ax.collections[0].get_facecolors(), expected_colors, alpha=0.5)
_check_colors(4, ax.collections[0].get_facecolors(), expected_colors)
class TestPolygonZPlotting:
@@ -321,18 +316,22 @@ class TestNonuniformGeometryPlotting:
self.series = GeoSeries([poly, line, point])
self.df = GeoDataFrame({'geometry': self.series, 'values': [1, 2, 3]})
def test_colormap(self):
def test_colors(self):
# default uniform color
ax = self.series.plot()
_check_colors(1, ax.collections[0].get_facecolors(), [MPL_DFT_COLOR])
_check_colors(1, ax.collections[1].get_edgecolors(), [MPL_DFT_COLOR])
_check_colors(1, ax.collections[2].get_facecolors(), [MPL_DFT_COLOR])
# colormap: different colors
ax = self.series.plot(cmap='RdYlGn')
cmap = plt.get_cmap('RdYlGn', 3)
# polygon gets extra alpha. See #266
_check_colors(1, ax.collections[0].get_facecolors(), [cmap(0)], alpha=0.5)
_check_colors(1, ax.collections[1].get_facecolors(), [cmap(1)], alpha=1) # line
_check_colors(1, ax.collections[2].get_facecolors(), [cmap(2)], alpha=1) # point
cmap = plt.get_cmap('RdYlGn')
exp_colors = cmap(np.arange(3) / (3 - 1))
_check_colors(1, ax.collections[0].get_facecolors(), [exp_colors[0]])
_check_colors(1, ax.collections[1].get_edgecolors(), [exp_colors[1]])
_check_colors(1, ax.collections[2].get_facecolors(), [exp_colors[2]])
def test_style_kwargs(self):
# markersize -> only the Point gets it
ax = self.series.plot(markersize=10)
assert ax.collections[2].get_sizes() == [10]
ax = self.df.plot(markersize=10)
@@ -378,8 +377,7 @@ class TestPlotCollections:
for i in range(self.N)])
def test_points(self):
# scatterplot does not yet accept list of colors in matplotlib 1.4.3
# if we change the default to uniform, this might work again
# failing with matplotlib 1.4.3 (edge stays black even when specified)
pytest.importorskip('matplotlib', '1.5.0')
from geopandas.plotting import plot_point_collection
@@ -422,12 +420,11 @@ class TestPlotCollections:
# default colormap
fig, ax = plt.subplots()
coll = plot_point_collection(ax, self.points, self.values)
fig.canvas.draw_idle()
cmap = plt.get_cmap()
expected_colors = cmap(np.arange(self.N))
# not sure why this is failing (gives only a single color, when
# testing outside of pytest, this works perfectly
# _check_colors(self.N, coll.get_facecolors(), expected_colors)
expected_colors = cmap(np.arange(self.N) / (self.N - 1))
_check_colors(self.N, coll.get_facecolors(), expected_colors)
# edgecolor depends on matplotlib version
# _check_colors(self.N, coll.get_edgecolors(), expected_colors)
def test_linestrings(self):
@@ -463,7 +460,8 @@ class TestPlotCollections:
ax.cla()
# pass through of kwargs
coll = plot_linestring_collection(ax, self.lines, linestyle='--')
coll = plot_linestring_collection(ax, self.lines, linestyle='--',
linewidth=1)
exp_ls = _style_to_linestring_onoffseq('dashed')
res_ls = coll.get_linestyle()[0]
assert res_ls[0] == exp_ls[0]
@@ -477,28 +475,28 @@ class TestPlotCollections:
# default colormap
coll = plot_linestring_collection(ax, self.lines, self.values)
fig.canvas.draw_idle()
cmap = plt.get_cmap()
expected_colors = cmap(np.arange(self.N))
# failing, see above with points
# _check_colors(self.N, coll.get_color(), expected_colors)
expected_colors = cmap(np.arange(self.N) / (self.N - 1))
_check_colors(self.N, coll.get_color(), expected_colors)
ax.cla()
# specify colormap
coll = plot_linestring_collection(ax, self.lines, self.values,
cmap='RdBu')
fig.canvas.draw_idle()
cmap = plt.get_cmap('RdBu')
expected_colors = cmap(np.arange(self.N))
# failing, see above with points
# _check_colors(self.N, coll.get_color(), expected_colors)
expected_colors = cmap(np.arange(self.N) / (self.N - 1))
_check_colors(self.N, coll.get_color(), expected_colors)
ax.cla()
# specify vmin/vmax
coll = plot_linestring_collection(ax, self.lines, self.values,
vmin=3, vmax=5)
fig.canvas.draw_idle()
cmap = plt.get_cmap()
expected_colors = cmap([0])
# failing, see above with points
# _check_colors(self.N, coll.get_color(), expected_colors)
_check_colors(self.N, coll.get_color(), expected_colors)
ax.cla()
def test_polygons(self):
@@ -511,31 +509,28 @@ class TestPlotCollections:
ax.cla()
# default: single default matplotlib color
# but with default alpha of 0.5 and black edgecolor
coll = plot_polygon_collection(ax, self.polygons)
_check_colors(self.N, coll.get_facecolor(), [MPL_DFT_COLOR] * self.N,
alpha=0.5)
_check_colors(self.N, coll.get_edgecolor(), ['k'] * self.N, alpha=0.5)
_check_colors(self.N, coll.get_facecolor(), [MPL_DFT_COLOR] * self.N)
_check_colors(self.N, coll.get_edgecolor(), ['k'] * self.N)
ax.cla()
# default: color sets both facecolor and edgecolor
# TODO but test fails for edge (still black)
coll = plot_polygon_collection(ax, self.polygons, color='g')
_check_colors(self.N, coll.get_facecolor(), ['g'] * self.N, alpha=0.5)
# _check_colors(self.N, coll.get_edgecolor(), ['g'] * self.N, alpha=0.5)
_check_colors(self.N, coll.get_facecolor(), ['g'] * self.N)
_check_colors(self.N, coll.get_edgecolor(), ['g'] * self.N)
ax.cla()
# only setting facecolor keeps default for edgecolor
coll = plot_polygon_collection(ax, self.polygons, facecolor='g')
_check_colors(self.N, coll.get_facecolor(), ['g'] * self.N, alpha=0.5)
_check_colors(self.N, coll.get_edgecolor(), ['k'] * self.N, alpha=0.5)
_check_colors(self.N, coll.get_facecolor(), ['g'] * self.N)
_check_colors(self.N, coll.get_edgecolor(), ['k'] * self.N)
ax.cla()
# custom facecolor and edgecolor
coll = plot_polygon_collection(ax, self.polygons, facecolor='g',
edgecolor='r')
_check_colors(self.N, coll.get_facecolor(), ['g'] * self.N, alpha=0.5)
_check_colors(self.N, coll.get_edgecolor(), ['r'] * self.N, alpha=0.5)
_check_colors(self.N, coll.get_facecolor(), ['g'] * self.N)
_check_colors(self.N, coll.get_edgecolor(), ['r'] * self.N)
ax.cla()
def test_polygons_values(self):
@@ -545,39 +540,40 @@ class TestPlotCollections:
# default colormap, edge is still black by default
coll = plot_polygon_collection(ax, self.polygons, self.values)
fig.canvas.draw_idle()
cmap = plt.get_cmap()
exp_colors = cmap(np.arange(self.N))
# failing, see above with points
# _check_colors(self.N, coll.get_facecolor(), exp_colors, alpha=0.5)
_check_colors(self.N, coll.get_edgecolor(), ['k'] * self.N, alpha=0.5)
exp_colors = cmap(np.arange(self.N) / (self.N - 1))
_check_colors(self.N, coll.get_facecolor(), exp_colors)
# edgecolor depends on matplotlib version
#_check_colors(self.N, coll.get_edgecolor(), ['k'] * self.N)
ax.cla()
# specify colormap
coll = plot_polygon_collection(ax, self.polygons, self.values,
cmap='RdBu')
fig.canvas.draw_idle()
cmap = plt.get_cmap('RdBu')
exp_colors = cmap(np.arange(self.N))
# failing, see above with points
# _check_colors(self.N, coll.get_facecolor(), exp_colors, alpha=0.5)
exp_colors = cmap(np.arange(self.N) / (self.N - 1))
_check_colors(self.N, coll.get_facecolor(), exp_colors)
ax.cla()
# specify vmin/vmax
coll = plot_polygon_collection(ax, self.polygons, self.values,
vmin=3, vmax=5)
fig.canvas.draw_idle()
cmap = plt.get_cmap()
exp_colors = cmap([0])
# failing, see above with points
# _check_colors(self.N, coll.get_facecolor(), exp_colors, alpha=0.5)
_check_colors(self.N, coll.get_facecolor(), exp_colors)
ax.cla()
# override edgecolor
coll = plot_polygon_collection(ax, self.polygons, self.values,
edgecolor='g')
fig.canvas.draw_idle()
cmap = plt.get_cmap()
exp_colors = cmap(np.arange(self.N))
# failing, see above with points
# _check_colors(self.N, coll.get_facecolor(), exp_colors, alpha=0.5)
_check_colors(self.N, coll.get_edgecolor(), ['g'] * self.N, alpha=0.5)
exp_colors = cmap(np.arange(self.N) / (self.N - 1))
_check_colors(self.N, coll.get_facecolor(), exp_colors)
_check_colors(self.N, coll.get_edgecolor(), ['g'] * self.N)
ax.cla()