gpt4 book ai didi

python - 使用 Matplotlib 的任意非线性颜色条

转载 作者:太空狗 更新时间:2023-10-30 02:38:47 26 4
gpt4 key购买 nike

我想使用 Networkx 和 Matplotlib 为网络的边缘着色,其中每个边缘 (i,j) 都被赋予一个值 G[i][j]['label'] 介于 0 和 1 之间。

但是,这些值通常要么非常接近于 0,要么非常接近 1。然后很难将颜色的变化可视化,因为所有东西要么非常红,要么非常蓝(使用 coolwarm 颜色图)。

然后,我的想法是应用一个过滤器 filtR,就像这些过滤器之一:

enter image description here

它只是一个多项式函数,提供从 [0,1] 到 [0,1] 的双射,并在 0 或 1 附近扩展更多值。如果需要,逆函数很容易处理。

现在,我只是将它应用到边缘的值,以定义它的颜色:

cm        = plt.get_cmap('coolwarm') 
cNorm = colors.Normalize(vmin=0., vmax=1.)
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=cm)
colorList = []

# The color is defined by filtR(G[i][j]['label'])
val_map = {(i,j): filtR(G[i][j]['label']) for (i,j) in G.edges()}
values = [scalarMap.to_rgba(val_map[e]) for e in G.edges()]
edges = nx.draw_networkx_edges(G,edge_color=values,edge_cmap=plt.get_cmap('coolwarm'))


# Definition of the colorbar :-(
sm = cmx.ScalarMappable(cmap=cmx.coolwarm)
sm.set_array(values)
plt.colorbar(sm)

现在的问题是:我想定义对应的colorbar。

现在,它显示了 filtR 函数对我的边缘的评估,这是没有意义的:过滤器的唯一目的是修改 [0,1] 区间上的颜色重新分配以提高图表的可读性。

例如,我得到:

enter image description here

我对左边部分很满意,但对右边部分不满意,颜色栏应该是这样的:

enter image description here

这里的 filter 函数显然不是最好的,但它应该为您提供更好的说明。

我试图在定义颜色条之前重新定义 values :

# Definition of the colorbar :-(

new_val_map = {(i,j): filtR(G[i][j]['label']) for (i,j) in G.edges()}
new_values = [scalarMap.to_rgba(val_map[e]) for e in G.edges()]

sm = cmx.ScalarMappable(cmap=cmx.coolwarm)
sm.set_array(new_values)
plt.colorbar(sm)

但是什么都没有改变。

我对 Matplotlib 的理解有点有限,所提供的代码已经是堆栈溢出答案的拼凑。

最佳答案

本质上,您根本不想更改颜色图。 Instaed 你想创建你的自定义规范化。为此,您可以子类化 matplotlib.colors.Normalize 并让它返回自定义函数的值。该函数需要将 vminvmax 之间的值作为输入并返回 [0,1] 范围内的值。

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.colors as mcolors


class MyNormalize(mcolors.Normalize):
def __call__(self, value, clip=None):
# function to normalize any input between vmin and vmax linearly to [0,1]
n = lambda x: (x-self.vmin)/(self.vmax-self.vmin)
# nonlinear function between [0,1] and [0,1]
f = lambda x,a: (2*x)**a*(2*x<1)/2. +(2-(2*(1-1*x))**a)*(2*x>=1)/2.
return np.ma.masked_array(f(n(value),0.5))


fig, (ax,ax2) = plt.subplots(ncols=2)

x = np.linspace(-0.3,1.2, num=101)
X = (np.sort(np.random.rand(100))*1.5-0.3)

norm= MyNormalize(vmin=-0.3, vmax=1.2)

ax.plot(x,norm(x))
im = ax2.imshow(X[::-1,np.newaxis], norm=norm, cmap="coolwarm", aspect="auto")
fig.colorbar(im)

plt.show()

enter image description here

所需颜色条的图像更像是一个部分线性函数,就像下面使用的蜜蜂一样。

class MyNormalize2(mcolors.Normalize):
def __call__(self, value, clip=None):
n = lambda x: self.vmin+(self.vmax-self.vmin)*x
x, y = [self.vmin, n(0.2), n(0.8), self.vmax], [0, 0.48,0.52, 1]
return np.ma.masked_array(np.interp(value, x, y))

enter image description here

关于python - 使用 Matplotlib 的任意非线性颜色条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46038206/

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