mirror of
https://github.com/wassname/geopandas.git
synced 2026-09-09 11:22:50 +08:00
BUG: fix incorrect colors with mixed geometry types and list of colors (#2420)
This commit is contained in:
+18
-6
@@ -325,7 +325,7 @@ def plot_series(
|
||||
----------
|
||||
s : Series
|
||||
The GeoSeries to be plotted. Currently Polygon,
|
||||
MultiPolygon, LineString, MultiLineString and Point
|
||||
MultiPolygon, LineString, MultiLineString, Point and MultiPoint
|
||||
geometries can be plotted.
|
||||
cmap : str (default None)
|
||||
The name of a colormap recognized by matplotlib. Any
|
||||
@@ -335,7 +335,7 @@ def plot_series(
|
||||
|
||||
tab10, tab20, Accent, Dark2, Paired, Pastel1, Set1, Set2
|
||||
|
||||
color : str (default None)
|
||||
color : str, np.array, pd.Series, List (default None)
|
||||
If specified, all objects will be colored uniformly.
|
||||
ax : matplotlib.pyplot.Artist (default None)
|
||||
axes on which to draw the plot
|
||||
@@ -414,6 +414,9 @@ def plot_series(
|
||||
)
|
||||
return ax
|
||||
|
||||
# have colors been given for all geometries?
|
||||
color_given = pd.api.types.is_list_like(color) and len(color) == len(s)
|
||||
|
||||
# if cmap is specified, create range of colors based on cmap
|
||||
values = None
|
||||
if cmap is not None:
|
||||
@@ -426,6 +429,10 @@ def plot_series(
|
||||
# decompose GeometryCollections
|
||||
geoms, multiindex = _flatten_multi_geoms(s.geometry, prefix="Geom")
|
||||
values = np.take(values, multiindex, axis=0) if cmap else None
|
||||
# ensure indexes are consistent
|
||||
if color_given and isinstance(color, pd.Series):
|
||||
color = color.reindex(s.index)
|
||||
expl_color = np.take(color, multiindex, axis=0) if color_given else color
|
||||
expl_series = geopandas.GeoSeries(geoms)
|
||||
|
||||
geom_types = expl_series.type
|
||||
@@ -443,8 +450,9 @@ def plot_series(
|
||||
# color overrides both face and edgecolor. As we want people to be
|
||||
# able to use edgecolor as well, pass color to facecolor
|
||||
facecolor = style_kwds.pop("facecolor", None)
|
||||
color_ = expl_color[poly_idx] if color_given else color
|
||||
if color is not None:
|
||||
facecolor = color
|
||||
facecolor = color_
|
||||
|
||||
values_ = values[poly_idx] if cmap else None
|
||||
_plot_polygon_collection(
|
||||
@@ -455,16 +463,20 @@ def plot_series(
|
||||
lines = expl_series[line_idx]
|
||||
if not lines.empty:
|
||||
values_ = values[line_idx] if cmap else None
|
||||
color_ = expl_color[line_idx] if color_given else color
|
||||
|
||||
_plot_linestring_collection(
|
||||
ax, lines, values_, color=color, cmap=cmap, **style_kwds
|
||||
ax, lines, values_, color=color_, cmap=cmap, **style_kwds
|
||||
)
|
||||
|
||||
# plot all Points in the same collection
|
||||
points = expl_series[point_idx]
|
||||
if not points.empty:
|
||||
values_ = values[point_idx] if cmap else None
|
||||
color_ = expl_color[point_idx] if color_given else color
|
||||
|
||||
_plot_point_collection(
|
||||
ax, points, values_, color=color, cmap=cmap, **style_kwds
|
||||
ax, points, values_, color=color_, cmap=cmap, **style_kwds
|
||||
)
|
||||
|
||||
plt.draw()
|
||||
@@ -524,7 +536,7 @@ def plot_dataframe(
|
||||
- 'hexbin' : hexbin plot.
|
||||
cmap : str (default None)
|
||||
The name of a colormap recognized by matplotlib.
|
||||
color : str (default None)
|
||||
color : str, np.array, pd.Series (default None)
|
||||
If specified, all objects will be colored uniformly.
|
||||
ax : matplotlib.pyplot.Artist (default None)
|
||||
axes on which to draw the plot
|
||||
|
||||
@@ -16,6 +16,7 @@ from shapely.geometry import (
|
||||
MultiPoint,
|
||||
MultiLineString,
|
||||
GeometryCollection,
|
||||
box,
|
||||
)
|
||||
|
||||
|
||||
@@ -871,6 +872,47 @@ class TestPolygonZPlotting:
|
||||
self.df.plot()
|
||||
|
||||
|
||||
class TestColorParamArray:
|
||||
def setup_method(self):
|
||||
geom = []
|
||||
color = []
|
||||
for a, b in [(0, 2), (4, 6)]:
|
||||
b = box(a, a, b, b)
|
||||
geom += [b, b.buffer(0.8).exterior, b.centroid]
|
||||
color += ["red", "green", "blue"]
|
||||
|
||||
self.gdf = GeoDataFrame({"geometry": geom, "color_rgba": color})
|
||||
self.mgdf = self.gdf.dissolve(self.gdf.type)
|
||||
|
||||
def test_color_single(self):
|
||||
ax = self.gdf.plot(color=self.gdf["color_rgba"])
|
||||
|
||||
_check_colors(
|
||||
4,
|
||||
np.concatenate([c.get_edgecolor() for c in ax.collections]),
|
||||
["green"] * 2 + ["blue"] * 2,
|
||||
)
|
||||
_check_colors(
|
||||
4,
|
||||
np.concatenate([c.get_facecolor() for c in ax.collections]),
|
||||
["red"] * 2 + ["blue"] * 2,
|
||||
)
|
||||
|
||||
def test_color_multi(self):
|
||||
ax = self.mgdf.plot(color=self.mgdf["color_rgba"])
|
||||
|
||||
_check_colors(
|
||||
4,
|
||||
np.concatenate([c.get_edgecolor() for c in ax.collections]),
|
||||
["green"] * 2 + ["blue"] * 2,
|
||||
)
|
||||
_check_colors(
|
||||
4,
|
||||
np.concatenate([c.get_facecolor() for c in ax.collections]),
|
||||
["red"] * 2 + ["blue"] * 2,
|
||||
)
|
||||
|
||||
|
||||
class TestGeometryCollectionPlotting:
|
||||
def setup_method(self):
|
||||
coll1 = GeometryCollection(
|
||||
|
||||
Reference in New Issue
Block a user