GeoPandas六边形几何绘制问题:自定义配色与图例展示
Hey there, let's work through this problem step by step — I've dealt with similar GeoPandas plotting glitches before, so let's start with the root cause of the distorted visuals, then nail the custom colors and proper legend.
First: Fix Geometry Topology (The Likely Culprit for Distortion)
Most of the time, wonky plots with polygons come down to invalid geometry (think self-intersections, overlaps, or malformed shapes). Let's check and fix that first:
# Check for invalid polygons invalid_rows = df_january[~df_january.geometry.is_valid] print(f"Found {len(invalid_rows)} invalid geometries") # Quick fix for common topology issues (buffer(0) works magic here) df_january['geometry'] = df_january.geometry.buffer(0)
After running this, try plotting again — odds are the distortion will be gone right away. If not, double-check your coordinate reference system (CRS): geographic CRS (like WGS84 lat/lon) can warp hexagons when plotting, so convert to a projected CRS (UTM works great for local areas):
# Auto-detect and convert to UTM projection df_january = df_january.to_crs(df_january.estimate_utm_crs())
Second: Custom Coloring + Legend for pred_labels (Discrete Categories)
Since pred_labels are discrete values (like 1, 3), we need to treat them as categories instead of continuous numbers — that's a common mistake that causes weird rendering. Here's how to set up custom colors and a clean legend:
import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap # Define your custom color mapping (match labels to your preferred shades) label_color_map = { 1: '#e6e6fa', # Light purple 3: '#9370db' # Dark purple } # Create a colormap aligned with your unique labels unique_labels = sorted(df_january['pred_labels'].unique()) custom_cmap = ListedColormap([label_color_map[label] for label in unique_labels]) # Plot with categorical handling enabled fig, ax = plt.subplots(figsize=(10, 8)) df_january.plot( column='pred_labels', cmap=custom_cmap, categorical=True, # Critical: tells GeoPandas this is discrete data legend=True, ax=ax ) # Optional: Tweak legend labels for clarity handles, current_labels = ax.get_legend_handles_labels() ax.legend(handles, [f"Label {label}" for label in unique_labels], title="Predicted Labels") plt.show()
The categorical=True flag is key here — without it, GeoPandas will try to treat your labels as continuous values, leading to incorrect color mapping and distorted visuals.
Third: Custom Coloring + Legend for color (Continuous Values)
Your color column is a continuous 0-1 range, so we'll use a gradient colormap and optimize the legend for readability:
import matplotlib.pyplot as plt from matplotlib.colors import LinearSegmentedColormap # Create a custom continuous purple gradient custom_purple_cmap = LinearSegmentedColormap.from_list( 'my_purples', ['#f0e6ff', '#9370db'], # Light to dark purple N=256 ) # Plot with legend customization fig, ax = plt.subplots(figsize=(10, 8)) color_plot = df_january.plot( column='color', cmap=custom_purple_cmap, legend=True, legend_kwds={ 'label': 'Color Intensity', 'shrink': 0.8, # Shrink legend to fit better 'orientation': 'horizontal' # Optional: horizontal legend for wider plots }, ax=ax ) plt.show()
Quick Extra Checks
- If you still see overlaps, check for duplicate geometries with
df_january.drop_duplicates(subset='geometry') - Verify no hexagons are overlapping with
df_january.geometry.overlay(df_january, how='intersection').empty— if this returnsFalse, you have overlapping shapes that need cleaning up
内容的提问来源于stack exchange,提问作者John Stud

