Matplotlib:如何使用用户输入更改颜色条渐变
Matplotlib: How to change colorbar gradient using user input
我想自定义具有特定值范围的颜色条(颜色图)。颜色范围应随给定参数 (Tup,Tmd,Tbt) 而变化,其中
- Tup:用户选择的上限值
- Tmid:用户选择的中点
- Tbt:用户选择的底点
中间色(青柠色)应在用户选择的 Tup 和 Tbt 之间,以 Tmd 为中点。
我尝试使用以下代码片段生成自定义颜色图,但无法使用用户提供的值来控制其范围。
cmap = LinearSegmentedColormap.from_list("", ["blue","gray","lime","gray","red"])
cax = ax.pcolor(data,cmap=cmap,edgecolors='k',vmin=0,vmax=100)
如何根据用户输入控制颜色图值?
您可以使用 LinearSegmentedColormap
to create the colormap, and DiverginNorm
的组合来定义端点和中心点。
演示(代码未优化,但展示了大致思路):
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
from matplotlib import colors
maxV = 100
minV = -100
centerV = -50
N=10
data = np.random.uniform(low=minV, high=maxV, size=(N,N))
cmap = colors.LinearSegmentedColormap.from_list('', ['blue','lime','red'])
norm = colors.DivergingNorm(vmin=minV, vcenter=centerV, vmax=maxV)
fig, (ax, axSlide1, axSlide2, axSlide3) = plt.subplots(4,1, gridspec_kw=dict(height_ratios=[100,5,5,5]))
im = ax.imshow(data, cmap=cmap, norm=norm)
cbar = fig.colorbar(im, ax=ax)
axcolor = 'lightgoldenrodyellow'
for sax in [axSlide1, axSlide2, axSlide3]:
sax.set_facecolor(axcolor)
smin = Slider(axSlide1, 'min', minV, maxV, valinit=minV)
scenter = Slider(axSlide2, 'center', minV, maxV, valinit=centerV)
smax = Slider(axSlide3, 'max', minV, maxV, valinit=maxV)
def update(val):
global cbar
minV = smin.val
maxV = smax.val
centerV = scenter.val
if minV>maxV:
minV=maxV
smin.set_val(minV)
if maxV<minV:
maxV=minV
smax.set_val(maxV)
if centerV<minV:
centerV = minV
scenter.set_val(centerV)
if centerV>maxV:
centerV = maxV
scenter.set_val(centerV)
#redraw with new normalization
norm = colors.DivergingNorm(vmin=minV, vcenter=centerV, vmax=maxV)
ax.cla()
cbar.ax.cla()
im = ax.imshow(data, cmap=cmap, norm=norm)
cbar = fig.colorbar(im, cax=cbar.ax)
fig.canvas.draw_idle()
smin.on_changed(update)
smax.on_changed(update)
scenter.on_changed(update)
plt.show()
我想自定义具有特定值范围的颜色条(颜色图)。颜色范围应随给定参数 (Tup,Tmd,Tbt) 而变化,其中
- Tup:用户选择的上限值
- Tmid:用户选择的中点
- Tbt:用户选择的底点
中间色(青柠色)应在用户选择的 Tup 和 Tbt 之间,以 Tmd 为中点。
我尝试使用以下代码片段生成自定义颜色图,但无法使用用户提供的值来控制其范围。
cmap = LinearSegmentedColormap.from_list("", ["blue","gray","lime","gray","red"])
cax = ax.pcolor(data,cmap=cmap,edgecolors='k',vmin=0,vmax=100)
如何根据用户输入控制颜色图值?
您可以使用 LinearSegmentedColormap
to create the colormap, and DiverginNorm
的组合来定义端点和中心点。
演示(代码未优化,但展示了大致思路):
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
from matplotlib import colors
maxV = 100
minV = -100
centerV = -50
N=10
data = np.random.uniform(low=minV, high=maxV, size=(N,N))
cmap = colors.LinearSegmentedColormap.from_list('', ['blue','lime','red'])
norm = colors.DivergingNorm(vmin=minV, vcenter=centerV, vmax=maxV)
fig, (ax, axSlide1, axSlide2, axSlide3) = plt.subplots(4,1, gridspec_kw=dict(height_ratios=[100,5,5,5]))
im = ax.imshow(data, cmap=cmap, norm=norm)
cbar = fig.colorbar(im, ax=ax)
axcolor = 'lightgoldenrodyellow'
for sax in [axSlide1, axSlide2, axSlide3]:
sax.set_facecolor(axcolor)
smin = Slider(axSlide1, 'min', minV, maxV, valinit=minV)
scenter = Slider(axSlide2, 'center', minV, maxV, valinit=centerV)
smax = Slider(axSlide3, 'max', minV, maxV, valinit=maxV)
def update(val):
global cbar
minV = smin.val
maxV = smax.val
centerV = scenter.val
if minV>maxV:
minV=maxV
smin.set_val(minV)
if maxV<minV:
maxV=minV
smax.set_val(maxV)
if centerV<minV:
centerV = minV
scenter.set_val(centerV)
if centerV>maxV:
centerV = maxV
scenter.set_val(centerV)
#redraw with new normalization
norm = colors.DivergingNorm(vmin=minV, vcenter=centerV, vmax=maxV)
ax.cla()
cbar.ax.cla()
im = ax.imshow(data, cmap=cmap, norm=norm)
cbar = fig.colorbar(im, cax=cbar.ax)
fig.canvas.draw_idle()
smin.on_changed(update)
smax.on_changed(update)
scenter.on_changed(update)
plt.show()