gpt4 book ai didi

python - 在 matplotlib 中更改颜色条渐变

转载 作者:行者123 更新时间:2023-11-28 20:16:05 27 4
gpt4 key购买 nike

我有一个随时间 (X) 演变的权重 (Y) 网格: enter image description here

我无法正确区分权重的变化,因为正权重和负权重之间的分布是不对称的;应识别空权重,因为这意味着未使用给定变量。

出于这些原因,我想更改颜色渐变以获得类似的效果(a 或 b): enter image description here

关于如何处理这个问题有什么想法吗?

最佳答案

matplotlib 中的颜色条将 0 到 1 之间的数字映射到颜色。为了将其他数字映射到颜色,您首先需要对范围 [0,1] 进行归一化。这通常是根据最小和最大数据自动完成的,或者通过对相应的绘图函数使用 vminvmax 参数来自动完成。在内部,规范化实例 matplotlib.colors.Normalize 用于执行规范化,默认情况下假定 vminvmax 之间的线性比例。

此处您需要一个非线性比例,它 (a) 将中间点移动到某个指定值,并且 (b) 挤压该值周围的颜色。

现在的想法是子类化 matplotlib.colors.Normalize 并让它返回满足条件 (a) 和 (b) 的映射。

一个选项可能是两个根函数的组合,如下所示。

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

class SqueezedNorm(matplotlib.colors.Normalize):
def __init__(self, vmin=None, vmax=None, mid=0, s1=2, s2=2, clip=False):
self.vmin = vmin # minimum value
self.mid = mid # middle value
self.vmax = vmax # maximum value
self.s1=s1; self.s2=s2
f = lambda x, zero,vmax,s: np.abs((x-zero)/(vmax-zero))**(1./s)*0.5
self.g = lambda x, zero,vmin,vmax, s1,s2: f(x,zero,vmax,s1)*(x>=zero) - \
f(x,zero,vmin,s2)*(x<zero)+0.5
matplotlib.colors.Normalize.__init__(self, vmin, vmax, clip)

def __call__(self, value, clip=None):
r = self.g(value, self.mid,self.vmin,self.vmax, self.s1,self.s2)
return np.ma.masked_array(r)


fig, (ax, ax2, ax3) = plt.subplots(nrows=3,
gridspec_kw={"height_ratios":[3,2,1], "hspace":0.25})

x = np.linspace(-13,4, 110)
norm=SqueezedNorm(vmin=-13, vmax=4, mid=0, s1=1.7, s2=4)

line, = ax.plot(x, norm(x))
ax.margins(0)
ax.set_ylim(0,1)

im = ax2.imshow(np.atleast_2d(x).T, cmap="Spectral_r", norm=norm, aspect="auto")
cbar = fig.colorbar(im ,cax=ax3,ax=ax2, orientation="horizontal")

enter image description here

该函数的选择使其独立于其参数,它将任何范围映射到范围[0,1],这样就可以使用颜色图。参数 mid 确定应将哪个值映射到颜色图的中间。在这种情况下,这将是 0。参数 s1s2 确定颜色图在两个方向上的压缩程度。

设置 mid = np.mean(vmin, vmax), s1=1, s2=1 将恢复原始缩放。

enter image description here

为了选择好的参数,可以使用一些 slider 来查看实时更新的绘图。

enter image description here

from matplotlib.widgets import Slider

midax = plt.axes([0.1, 0.04, 0.2, 0.03], facecolor="lightblue")
s1ax = plt.axes([0.4, 0.04, 0.2, 0.03], facecolor="lightblue")
s2ax = plt.axes([0.7, 0.04, 0.2, 0.03], facecolor="lightblue")

mid = Slider(midax, 'Midpoint', x[0], x[-1], valinit=0)
s1 = Slider(s1ax, 'S1', 0.5, 6, valinit=1.7)
s2 = Slider(s2ax, 'S2', 0.5, 6, valinit=4)


def update(val):
norm=SqueezedNorm(vmin=-13, vmax=4, mid=mid.val, s1=s1.val, s2=s2.val)
im.set_norm(norm)
cbar.update_bruteforce(im)
line.set_ydata(norm(x))
fig.canvas.draw_idle()

mid.on_changed(update)
s1.on_changed(update)
s2.on_changed(update)

fig.subplots_adjust(bottom=0.15)

关于python - 在 matplotlib 中更改颜色条渐变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44432693/

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