gpt4 book ai didi

matplotlib - 提取分段色彩图边界位置

转载 作者:行者123 更新时间:2023-12-02 19:16:20 27 4
gpt4 key购买 nike

我正在努力在 Matplotlib 中制作自定义颜色图。

据我了解,通过颜色条,我们可以将连续的值范围映射到颜色图中定义的颜色“光谱”。我正在制作一个自定义分段颜色图来覆盖离散的值范围。

我的代码:

colors = ['#FBE9BD', '#F2C370', '#E58B48', '#C35D30', '#A12F29']
cmap1 = LinearSegmentedColormap.from_list("mycmap", colors, N=5)

我着色的数据的值范围为 [50, 450]。我的理解是,这个颜色条将把这个范围(最大 - 最小)划分为五个等距的小部分,并根据上面提供的数组为其分配一个颜色值。我的问题是,是否有任何简单的方法可以从此颜色图中提取边界范围?我想将每个 bin 范围(即 50-120、121-175)的值映射到一个图例出现在其各自颜色旁边。

第二个问题 - 假设我们将 N=5 的值增加到 N=10。无需在颜色数组中提供任何其他颜色。现在我们将拥有比不同颜色值更多的子类别。这里会发生什么,一些垃圾箱共享相同的颜色分配吗?

任何信息或示例的链接将不胜感激。

最佳答案

以下代码和绘图尝试说明正在发生的情况。

LinearSegmentedColormap.from_list("", Colors) 在内部创建一个平滑的颜色图,在本例中使用值 0、0.25、0.5、0.75 和 1 的 5 种颜色(即范围 0-1 均匀分布)分成 5-1=4 个相等的空间。中间的位置会平滑插值。当您设置 N 时,N 区域将被放入 0-1 范围内。例如,使用 N=10,设置 10 个区域(使用 11 个边界)。每个区域的颜色值是通过将 0-1 之间的平滑颜色范围除以 N 来获得的(因此,不是 N+1)地位平等。

现在,将外部值 50-450 映射到内部值 0-1 a norm用来。默认情况下,使用数据的最小值和最大值。 vmin 和/或 vmax 可以设置明确的最小值和最大值。 (除此之外,还可以指定显式范数函数。)

为了计算外部值的边界,需要将范围 50-450 分割成 N 个相等的区域,即 N+1 个边界。 np.linspace(50, 450, N+1) 是一个 numpy 函数,它将这些边界值创建到数组中。

from matplotlib import pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
from matplotlib.cm import ScalarMappable
import numpy as np

colors = ['#FBE9BD', '#F2C370', '#E58B48', '#C35D30', '#A12F29']
cmap1 = LinearSegmentedColormap.from_list("mycmap1", colors, N=10)

minval = 50
maxval = 450
bounds = np.linspace(minval, maxval, cmap1.N + 1)
x = np.random.uniform(size=1000)
y = np.random.uniform(minval, maxval, size=x.size)
plt.scatter(x, y, c=y, vmin=minval, vmax=maxval, cmap=cmap1)

cbar = plt.colorbar(ScalarMappable(cmap=LinearSegmentedColormap.from_list("mycmap1", colors, N=256)),
label='Complete colormap', ticks=np.linspace(0, 1, len(colors)))
cbar.ax.set_yticklabels(colors)
plt.colorbar(ticks=bounds, label=f'LinearSegmentedColormap N={cmap1.N}')
plt.show()

左边N=5,右边N=10

illustrating plot

下图显示了相同的情况,但颜色更容易区分。平滑颜色条上的粗标记显示了分段颜色条的确切颜色来源。

more diverse colors

PS:以类似的方式创建图例:

from matplotlib import pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
from matplotlib.lines import Line2D
import numpy as np

colors = ['#FBE9BD', '#F2C370', '#E58B48', '#C35D30', '#A12F29']

cmap1 = LinearSegmentedColormap.from_list("mycmap1", colors, N=10)

minval = 50
maxval = 450
bounds = np.linspace(minval, maxval, cmap1.N + 1)
x = np.random.uniform(size=1000)
y = np.random.uniform(minval, maxval, size=x.size)
plt.scatter(x, y, c=y, vmin=minval, vmax=maxval, cmap=cmap1)

handles = [Line2D([], [], color=cmap1(i / (cmap1.N - 1)),
marker='o', ls='', label=f'{bounds[i]:.0f}-{bounds[i+1]:.0f}')
for i in range(cmap1.N) if i < 6 or i == cmap1.N-1]
plt.legend(handles=handles, bbox_to_anchor=[1.02, 1.02], loc='upper left')
plt.tight_layout()
plt.show()

legend example

关于matplotlib - 提取分段色彩图边界位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63663000/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com