如何提取并可视化多条2D红色线条的高密度交叉区域?
问题
我用不同颜色的2D线条连接多个数据点,但线条数量多的时候,很难区分大部分线条重叠或交叉的区域。以下是我的绘图脚本:
ax.scatter(rcv[:,0], rcv[:,1], c='b', marker='v',s=190,label= "End") ax.scatter(src[:,0], src[:,1], c='r', marker='*',s=120,label= "Start") if status=="High": x_values = [x1, x2] y_values = [y1, y2] plt.plot(x_values, y_values, 'k-', linewidth=0.5,alpha=0.5) fig.canvas.draw() else: x_values = [x1, x2] y_values = [y1, y2] plt.plot(x_values, y_values, 'r-', linewidth=0.5,alpha=0.5) fig.canvas.draw()
脚本中绘制了若干红色和黑色线条,我希望提取红色线条交叉密度较高的区域(支持用户自定义交叉数量阈值),恳请提供可行的解决方案建议。
解决方案建议
方法1:网格密度统计法
核心思路是把绘图区域拆分成均匀网格,统计每个网格内经过的红色线条数量,再根据阈值筛选高密度区域。
实现代码示例:
import numpy as np # 第一步:提前收集所有红色线条的线段数据 red_lines = [] # 在绘图的else分支中,把每条红线的(x1,y1,x2,y2)追加到这个列表 # 第二步:定义网格范围与分辨率 x_min, x_max = ax.get_xlim() y_min, y_max = ax.get_ylim() grid_size = 50 # 网格数量,可根据需求调整 x_grid = np.linspace(x_min, x_max, grid_size) y_grid = np.linspace(y_min, y_max, grid_size) density_grid = np.zeros((grid_size-1, grid_size-1)) # 第三步:判断线段是否与网格相交的辅助函数 def line_intersects_grid(x1, y1, x2, y2, grid_x_left, grid_x_right, grid_y_bottom, grid_y_top): # 先判断线段端点是否在网格内 in_grid = (grid_x_left <= x1 <= grid_x_right and grid_y_bottom <= y1 <= grid_y_top) or \ (grid_x_left <= x2 <= grid_x_right and grid_y_bottom <= y2 <= grid_y_top) if in_grid: return True # 简化判断:检查线段是否穿过网格边界(如需更精确可引入专业线段-矩形相交算法) return False # 第四步:统计每个网格的线条覆盖数 for x1, y1, x2, y2 in red_lines: for i in range(grid_size-1): for j in range(grid_size-1): grid_x_left = x_grid[i] grid_x_right = x_grid[i+1] grid_y_bottom = y_grid[j] grid_y_top = y_grid[j+1] if line_intersects_grid(x1, y1, x2, y2, grid_x_left, grid_x_right, grid_y_bottom, grid_y_top): density_grid[j, i] += 1 # 第五步:自定义阈值并可视化高密度区域 threshold = 10 # 用户可根据需求调整 high_density_mask = density_grid >= threshold for i in range(grid_size-1): for j in range(grid_size-1): if high_density_mask[j, i]: rect = plt.Rectangle((x_grid[i], y_grid[j]), x_grid[i+1]-x_grid[i], y_grid[j+1]-y_grid[j], facecolor='yellow', alpha=0.3) ax.add_patch(rect)
方法2:基于像素的热力图法
利用画布像素统计红色线条的覆盖次数,将其转换为热力图后筛选高密度区域。
实现代码示例:
# 第一步:创建空白画布单独绘制红色线条 fig_density, ax_density = plt.subplots(figsize=fig.get_size_inches(), dpi=fig.dpi) ax_density.set_xlim(ax.get_xlim()) ax_density.set_ylim(ax.get_ylim()) ax_density.set_facecolor('black') # 黑色背景,白色线条便于统计 # 第二步:绘制所有红色线条 for x1, y1, x2, y2 in red_lines: ax_density.plot([x1, x2], [y1, y2], 'w-', linewidth=0.5) # 第三步:提取画布像素数据 fig_density.canvas.draw() width, height = fig_density.canvas.get_width_height() pixel_data = np.frombuffer(fig_density.canvas.tostring_rgb(), dtype=np.uint8).reshape(height, width, 3) white_channel = pixel_data[:, :, 0] # 白色线条区域值为255,覆盖次数越多值越高 plt.close(fig_density) # 第四步:自定义阈值筛选高密度像素 threshold = 200 # 值越高,要求线条覆盖次数越多 high_density_pixels = white_channel >= threshold # 第五步:将高密度区域叠加到原图 ax.imshow(high_density_pixels, extent=[x_min, x_max, y_min, y_max], origin='lower', cmap='YlOrRd', alpha=0.3)
方法3:交点密度统计法
直接计算所有红色线条间的交点,统计交点在各区域的分布密度,筛选超过阈值的区域。
实现代码示例:
# 第一步:计算两条线段交点的辅助函数 def get_line_intersection(x1, y1, x2, y2, x3, y3, x4, y4): denom = (x1 - x2)*(y3 - y4) - (y1 - y2)*(x3 - x4) if denom == 0: return None # 线段平行或重合 t_num = (x1 - x3)*(y3 - y4) - (y1 - y3)*(x3 - x4) u_num = (x1 - x3)*(y1 - y2) - (y1 - y3)*(x1 - x2) t = t_num / denom u = -u_num / denom if 0 <= t <= 1 and 0 <= u <= 1: x = x1 + t*(x2 - x1) y = y1 + t*(y2 - y1) return (x, y) return None # 第二步:计算所有红色线条间的交点 intersections = [] n_lines = len(red_lines) for i in range(n_lines): x1, y1, x2, y2 = red_lines[i] for j in range(i+1, n_lines): x3, y3, x4, y4 = red_lines[j] pt = get_line_intersection(x1, y1, x2, y2, x3, y3, x4, y4) if pt is not None: intersections.append(pt) # 第三步:统计交点的网格密度 if intersections: xs, ys = zip(*intersections) x_min, x_max = min(xs), max(xs) y_min, y_max = min(ys), max(ys) grid_size = 30 x_grid = np.linspace(x_min, x_max, grid_size) y_grid = np.linspace(y_min, y_max, grid_size) density, _, _ = np.histogram2d(xs, ys, bins=[x_grid, y_grid]) # 第四步:自定义阈值并可视化 threshold = 5 # 交点数量阈值,用户可调整 high_density_mask = density >= threshold for i in range(grid_size-1): for j in range(grid_size-1): if high_density_mask[j, i]: rect = plt.Rectangle((x_grid[i], y_grid[j]), x_grid[i+1]-x_grid[i], y_grid[j+1]-y_grid[j], facecolor='orange', alpha=0.4) ax.add_patch(rect)
内容的提问来源于stack exchange,提问作者Aqeel
相关产品推荐
相关产品推荐

