如何用Python的Shapely绘制并着色重叠圆?解决相关技术问题
问题描述
尝试用Python的Shapely库绘制并着色重叠圆,查阅示例后仍遇到废弃函数(如cascaded_union)相关问题。现有代码能绘制圆的轮廓,但希望为圆填充自定义颜色,且重叠区域呈现混合色,不清楚如何在一系列缓冲点上执行unary_union操作,寻求帮助或其他实现方法。
现有代码:
import matplotlib.pyplot as plt from shapely.geometry import Point, Polygon, MultiPoint, MultiPolygon def plot_coords(coords): pts = list(coords) x, y = zip(*pts) plt.plot(x,y) def plot_polys(polys): for poly in polys: plot_coords(poly.exterior.coords) points = [Point(0, 0), Point(2,0), Point(1,2), Point(-1,2), Point(-2,0), Point(-1,-2), Point(1,-2)] for point in points: plot_polys([point.buffer(2.2)]) plt.show()
解决方案
方法1:Matplotlib直接填充带透明度的颜色
无需复杂的Shapely运算,直接利用Matplotlib的填充功能,给每个圆设置半透明颜色,重叠区域会自然呈现混合效果,是最简便的实现方式。
修改后的代码:
import matplotlib.pyplot as plt from shapely.geometry import Point # 自定义每个圆的填充色,数量与圆的数量对应 colors = ['#ff7f7f', '#ffbf7f', '#ffff7f', '#7fff7f', '#7fffff', '#7f7fff', '#ff7fff'] points = [Point(0, 0), Point(2,0), Point(1,2), Point(-1,2), Point(-2,0), Point(-1,-2), Point(1,-2)] plt.figure(figsize=(8,8)) for idx, point in enumerate(points): # 生成圆的多边形对象 circle = point.buffer(2.2) # 提取圆的坐标 x, y = circle.exterior.xy # 填充颜色,alpha控制透明度(0-1,值越小越透明) plt.fill(x, y, color=colors[idx], alpha=0.5) # 可选:绘制圆的黑色轮廓,增强辨识度 plt.plot(x, y, color='black', linewidth=0.5) # 保持坐标轴比例一致,避免圆变形 plt.axis('equal') plt.show()
方法2:用Shapely的unary_union精准控制重叠区域颜色
如果需要对不同重叠次数的区域设置差异化颜色(比如仅单个圆覆盖的区域用浅红,两个圆重叠的区域用深红),可以通过unary_union结合差集运算提取不同层级的重叠区域。
修改后的代码:
import matplotlib.pyplot as plt from shapely.geometry import Point from shapely.ops import unary_union points = [Point(0, 0), Point(2,0), Point(1,2), Point(-1,2), Point(-2,0), Point(-1,-2), Point(1,-2)] # 生成所有圆的多边形列表 circles = [point.buffer(2.2) for point in points] # 定义不同重叠次数对应的颜色 overlap_colors = { 1: '#ffcccc', # 仅单个圆覆盖的区域 2: '#ff9999', # 两个圆重叠的区域 3: '#ff6666', # 三个圆重叠的区域 # 可根据实际重叠情况扩展更多层级 } plt.figure(figsize=(8,8)) # 绘制仅单个圆覆盖的区域 for i, circle in enumerate(circles): # 计算当前圆减去其他所有圆的并集,得到唯一覆盖区域 others = unary_union(circles[:i] + circles[i+1:]) single_area = circle.difference(others) if not single_area.is_empty: # 处理可能的MultiPolygon类型,遍历子几何对象 if hasattr(single_area, 'geoms'): for geom in single_area.geoms: x, y = geom.exterior.xy plt.fill(x, y, color=overlap_colors[1]) else: x, y = single_area.exterior.xy plt.fill(x, y, color=overlap_colors[1]) # 绘制仅两个圆重叠的区域(示例,可扩展到更多重叠层级) for i in range(len(circles)): for j in range(i+1, len(circles)): # 计算两个圆的交集 overlap = circles[i].intersection(circles[j]) if overlap.is_empty: continue # 减去其他所有圆的覆盖,得到仅这两个圆重叠的区域 others = unary_union(circles[:i] + circles[i+1:j] + circles[j+1:]) double_area = overlap.difference(others) if not double_area.is_empty: if hasattr(double_area, 'geoms'): for geom in double_area.geoms: x, y = geom.exterior.xy plt.fill(x, y, color=overlap_colors[2]) else: x, y = double_area.exterior.xy plt.fill(x, y, color=overlap_colors[2]) # 绘制所有圆的轮廓(可选) for circle in circles: x, y = circle.exterior.xy plt.plot(x, y, color='black', linewidth=0.5) plt.axis('equal') plt.show()
关键说明:
unary_union是cascaded_union的替代函数,直接传入几何对象列表即可计算并集,无需循环调用。- 若运算结果为
MultiPolygon类型,需遍历其geoms属性逐个绘制子区域。 - 方法2适合需要精准控制重叠层级颜色的场景,但计算量会随圆的数量增加而上升。
内容的提问来源于stack exchange,提问作者Doda
相关产品推荐
相关产品推荐

