如何在Matplotlib中绘制分段颜色折线图及复杂几何图案?
1. 如何在Matplotlib中创建具有不同颜色分段的折线图?
方法一:拆分数据分段绘制
适合简单分段场景,将折线按需求拆分后逐个绘制,指定对应颜色:
import matplotlib.pyplot as plt import numpy as np # 生成示例数据 x = np.linspace(0, 10, 50) y = np.sin(x) # 定义分段索引与对应颜色 segments = [ (0, 15, 'red'), (15, 30, 'blue'), (30, 50, 'green') ] plt.figure(figsize=(10, 4)) for start, end, color in segments: plt.plot(x[start:end], y[start:end], color=color, linewidth=2) plt.title('分段颜色折线图') plt.show()
方法二:使用LineCollection(高效多分段)
针对大量分段场景,通过LineCollection一次性创建多线段,效率更高:
import matplotlib.pyplot as plt from matplotlib.collections import LineCollection import numpy as np x = np.linspace(0, 10, 50) y = np.sin(x) # 构造线段列表:每个线段为[[x1,y1], [x2,y2]]格式的数组 points = np.column_stack((x, y)) segments = np.array([points[i:i+2] for i in range(len(points)-1)]) # 为每个线段分配颜色(示例用y值映射渐变颜色) colors = plt.cm.viridis(y[:-1]) plt.figure(figsize=(10, 4)) lc = LineCollection(segments, colors=colors, linewidth=2) ax = plt.gca() ax.add_collection(lc) ax.set_xlim(x.min(), x.max()) ax.set_ylim(y.min()-0.1, y.max()+0.1) plt.colorbar(lc, label='Y值') plt.title('渐变颜色分段折线图') plt.show()
2. 优化复杂几何图案的绘制方法
问题分析
当前用白色小圆叠加模拟裁剪的方式,无法精准匹配目标图案的镂空形状。目标图案的镂空区域是相邻黑色大圆的重叠部分及中心正六边形区域,需通过几何布尔运算精准生成。
优化方案:使用几何布尔运算(结合Shapely)
通过Shapely库处理图形的交集、差集运算,直接生成需要保留的黑色区域,替代“叠加白色覆盖”的粗糙方法。
优化后代码
import matplotlib.pyplot as plt import numpy as np from shapely.geometry import Point, Polygon from shapely.ops import unary_union from matplotlib.patches import PathPatch from matplotlib.path import Path def shape_to_patch(shape, color): """将Shapely几何对象转换为Matplotlib PathPatch""" coords = list(shape.exterior.coords) if hasattr(shape, 'interiors'): for interior in shape.interiors: coords += list(interior.coords)[::-1] path = Path(coords) return PathPatch(path, facecolor=color, edgecolor=None) plt.figure(figsize=(8, 8)) ax = plt.gca() ax.set_aspect('equal') # 参数设置 R = 1.5 # 大圆半径 center_distance = 1.0 # 大圆中心到原点的距离 num_circles = 6 # 创建所有大圆的Shapely对象 big_circles = [] for i in range(num_circles): angle = i * (2 * np.pi / num_circles) cx = center_distance * np.cos(angle) cy = center_distance * np.sin(angle) big_circles.append(Point(cx, cy).buffer(R)) # 创建中心正六边形(目标图案中心的白色区域) hex_vertices = [] for i in range(num_circles): angle = i * (2 * np.pi / num_circles) x = center_distance * np.cos(angle) y = center_distance * np.sin(angle) hex_vertices.append((x, y)) center_hex = Polygon(hex_vertices) # 为每个大圆计算需要保留的区域 for i in range(num_circles): current_circle = big_circles[i] # 获取相邻的两个大圆 left_neighbor = big_circles[(i-1) % num_circles] right_neighbor = big_circles[(i+1) % num_circles] # 计算需要减去的区域:相邻两圆的交集 + 中心六边形 subtract_region = unary_union([ current_circle.intersection(left_neighbor), current_circle.intersection(right_neighbor), center_hex ]) # 得到最终要绘制的黑色区域 final_shape = current_circle.difference(subtract_region) # 添加到画布 ax.add_patch(shape_to_patch(final_shape, 'black')) # 设置坐标轴 plt.xlim([-3, 3]) plt.ylim([-3, 3]) plt.axis('off') plt.tight_layout() plt.show()
代码说明
- Shapely几何对象:用
Point.buffer(R)创建圆形,Polygon创建中心正六边形,支持灵活的布尔运算。 - 布尔运算:每个大圆减去与相邻两圆的交集(即目标图案的“缺口”),再减去中心正六边形,得到精准的黑色区域。
- 图形转换:将Shapely生成的多边形转换为Matplotlib的
PathPatch,直接添加到坐标轴绘制。
内容的提问来源于stack exchange,提问作者qmoi
相关产品推荐
相关产品推荐

