如何基于颜色映射实现按线段长度为线段着色?
解决方案:让颜色渐变匹配线段实际长度
我完全get到你的需求了——你想让线段的颜色渐变直观反映它的实际长度,而不是当前跟着x轴位置走的方式。之前的问题在于:对角线线段用了完整的0-1颜色范围(对应它的长度≈1.41),但上方线段因为x轴范围是0到0.5,颜色只用到了0-0.5区间,这和它实际长度是对角线的0.8倍完全不匹配。
核心思路
要解决这个问题,我们需要把颜色映射的输入值从「x轴位置」转换为「线段长度占参考线段的比例」:
- 先计算参考线段(对角线)的总长度
- 计算目标线段的实际总长度,得到它和参考线段的长度比例
- 用这个比例来生成颜色映射的输入数组,让颜色范围和线段长度占比一一对应
修改后的完整代码
import numpy as np import matplotlib.pyplot as plt from matplotlib.collections import LineCollection from matplotlib.colors import LinearSegmentedColormap x_nom = [0, 1] y_nom = [0, 1] # x,y coordinates x1 = 0 x2 = 0.8 y1 = 0 y2 = 1 x1_2 = 0 x2_2 = 1 y1_2 = 0 y2_2 = 1 # create segments from coordinates x_coords = np.linspace(x1, x2, 100) y_coords = np.linspace(y1, y2, 100) x_coords_2 = np.linspace(x1_2, x2_2, 100) y_coords_2 = np.linspace(y1_2, y2_2, 100) # 计算参考线段(对角线)和当前线段的真实长度,得到长度比例 l_nom = np.sqrt((x_nom[1]-x_nom[0])**2 + (y_nom[1]-y_nom[0])**2) l = np.sqrt((x2 - x1)**2 + (y2 - y1)**2) length_ratio = l / l_nom # 生成对应长度比例的颜色映射输入数组 res_ar = np.linspace(0, length_ratio, len(x_coords)) # 对角线线段作为参考,保持0-1的完整颜色范围 res_ar_2 = np.linspace(0, 1, len(x_coords_2)) # reshape array to fit matplotlib segmentation points = np.array([x_coords, y_coords]).T.reshape(-1, 1, 2) points_2 = np.array([x_coords_2, y_coords_2]).T.reshape(-1, 1, 2) segments = np.concatenate([points[:-1], points[1:]], axis=1) segments_2 = np.concatenate([points_2[:-1], points_2[1:]], axis=1) fig, ax = plt.subplots(figsize=(5,5)) # create custom colormap cvals = [0., 1.] colors = ['black', 'white'] norm = plt.Normalize(min(cvals), max(cvals)) tuples = list(zip(map(norm, cvals), colors)) cmap = LinearSegmentedColormap.from_list('', tuples) # plot segmented line lc = LineCollection(segments, cmap=cmap, norm=norm) lc_2 = LineCollection(segments_2, cmap=cmap, norm=norm) lc.set_array(res_ar) lc_2.set_array(res_ar_2) ax.add_collection(lc) ax.add_collection(lc_2) # 调整坐标轴范围,确保线段完整显示 ax.set_xlim(0, 1.1) ax.set_ylim(0, 1.1) plt.show()
关键修改说明
- 计算线段长度时,用
(x2-x1)和(y2-y1)的平方和开根号,这才是线段的真实欧几里得长度 - 直接生成从0到
length_ratio的res_ar数组,比原代码的计算方式更直观,效果完全一致 - 对角线线段保持0-1的颜色范围,因为它是我们的长度参考基准
这样修改后,上方线段的颜色渐变就会覆盖0到对应长度比例的区间,完美实现了「颜色渐变直观表示线段长度」的需求。
内容的提问来源于stack exchange,提问作者Artur Müller Romanov
相关产品推荐
相关产品推荐

