Python 在 matplotlib 中设置颜色条范围
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3373256/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set Colorbar Range in matplotlib
提问by Paul
I have the following code:
我有以下代码:
import matplotlib.pyplot as plt
cdict = {
'red' : ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
'green': ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
'blue' : ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}
cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)
plt.clf()
plt.pcolor(X, Y, v, cmap=cm)
plt.loglog()
plt.xlabel('X Axis')
plt.ylabel('Y Axis')
plt.colorbar()
plt.show()
So this produces a graph of the values 'v' on the axes X vs Y, using the specified colormap. The X and Y axes are perfect, but the colormap spreads between the min and max of v. I would like to force the colormap to range between 0 and 1.
因此,这会使用指定的颜色图生成 X 轴与 Y 轴上的值“v”的图形。X 和 Y 轴是完美的,但颜色图在 v 的最小值和最大值之间传播。我想强制颜色图的范围在 0 和 1 之间。
I thought of using:
我想过使用:
plt.axis(...)
To set the ranges of the axes, but this only takes arguments for the min and max of X and Y, not the colormap.
设置轴的范围,但这仅需要 X 和 Y 的最小值和最大值的参数,而不是颜色图。
Edit:
编辑:
For clarity, let's say I have one graph whose values range (0 ... 0.3), and another graph whose values (0.2 ... 0.8).
为清楚起见,假设我有一个值范围为 (0 ... 0.3) 的图和另一个值范围为 (0.2 ... 0.8) 的图。
In both graphs, I will want the range of the colorbar to be (0 ... 1). In both graphs, I want this range of colour to be identical using the full range of cdict above (so 0.25 in both graphs will be the same colour). In the first graph, all colours between 0.3 and 1.0 won't feature in the graph, but will in the colourbar key at the side. In the other, all colours between 0 and 0.2, and between 0.8 and 1 will not feature in the graph, but will in the colourbar at the side.
在这两个图中,我希望颜色条的范围为 (0 ... 1)。在这两个图中,我希望使用上述 cdict 的完整范围来使这个颜色范围相同(因此两个图中的 0.25 将是相同的颜色)。在第一个图表中,0.3 和 1.0 之间的所有颜色都不会出现在图表中,但会出现在旁边的颜色条键中。另一方面,0 到 0.2 之间和 0.8 到 1 之间的所有颜色都不会出现在图表中,但会出现在侧面的颜色栏中。
采纳答案by tom10
Using vminand vmaxforces the range for the colors. Here's an example:
使用vmin和vmax强制颜色范围。下面是一个例子:
import matplotlib as m
import matplotlib.pyplot as plt
import numpy as np
cdict = {
'red' : ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
'green': ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
'blue' : ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}
cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)
x = np.arange(0, 10, .1)
y = np.arange(0, 10, .1)
X, Y = np.meshgrid(x,y)
data = 2*( np.sin(X) + np.sin(3*Y) )
def do_plot(n, f, title):
#plt.clf()
plt.subplot(1, 3, n)
plt.pcolor(X, Y, f(data), cmap=cm, vmin=-4, vmax=4)
plt.title(title)
plt.colorbar()
plt.figure()
do_plot(1, lambda x:x, "all")
do_plot(2, lambda x:np.clip(x, -4, 0), "<0")
do_plot(3, lambda x:np.clip(x, 0, 4), ">0")
plt.show()
回答by nikow
Not sure if this is the most elegant solution (this is what I used), but you could scale your data to the range between 0 to 1 and then modify the colorbar:
不确定这是否是最优雅的解决方案(这是我使用的),但您可以将数据缩放到 0 到 1 之间的范围,然后修改颜色条:
import matplotlib as mpl
...
ax, _ = mpl.colorbar.make_axes(plt.gca(), shrink=0.5)
cbar = mpl.colorbar.ColorbarBase(ax, cmap=cm,
norm=mpl.colors.Normalize(vmin=-0.5, vmax=1.5))
cbar.set_clim(-2.0, 2.0)
With the two different limits you can control the range and legend of the colorbar. In this example only the range between -0.5 to 1.5 is show in the bar, while the colormap covers -2 to 2 (so this could be your data range, which you record before the scaling).
通过两个不同的限制,您可以控制颜色条的范围和图例。在此示例中,条形图中仅显示 -0.5 到 1.5 之间的范围,而颜色图涵盖 -2 到 2(因此这可能是您在缩放前记录的数据范围)。
So instead of scaling the colormap you scale your data and fit the colorbar to that.
因此,不是缩放颜色图,而是缩放数据并使颜色条适合它。
回答by Amro
回答by G M
Using figure environment and .set_clim()
使用图形环境和 .set_clim()
Could be easier and safer this alternative if you have multiple plots:
如果您有多个地块,这种替代方法可能更容易、更安全:
import matplotlib as m
import matplotlib.pyplot as plt
import numpy as np
cdict = {
'red' : ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
'green': ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
'blue' : ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}
cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)
x = np.arange(0, 10, .1)
y = np.arange(0, 10, .1)
X, Y = np.meshgrid(x,y)
data = 2*( np.sin(X) + np.sin(3*Y) )
data1 = np.clip(data,0,6)
data2 = np.clip(data,-6,0)
vmin = np.min(np.array([data,data1,data2]))
vmax = np.max(np.array([data,data1,data2]))
fig = plt.figure()
ax = fig.add_subplot(131)
mesh = ax.pcolormesh(data, cmap = cm)
mesh.set_clim(vmin,vmax)
ax1 = fig.add_subplot(132)
mesh1 = ax1.pcolormesh(data1, cmap = cm)
mesh1.set_clim(vmin,vmax)
ax2 = fig.add_subplot(133)
mesh2 = ax2.pcolormesh(data2, cmap = cm)
mesh2.set_clim(vmin,vmax)
# Visualizing colorbar part -start
fig.colorbar(mesh,ax=ax)
fig.colorbar(mesh1,ax=ax1)
fig.colorbar(mesh2,ax=ax2)
fig.tight_layout()
# Visualizing colorbar part -end
plt.show()
A single colorbar
单个颜色条
The best alternative is then to use a single color bar for the entire plot. There are different ways to do that, thistutorial is very useful for understanding the best option. I prefer this solution that you can simply copy and paste instead of the previous visualizing colorbar partof the code.
最好的选择是对整个绘图使用单个颜色条。有不同的方法可以做到这一点,本教程对于理解最佳选择非常有用。我更喜欢这个解决方案,您可以简单地复制和粘贴,而不是之前的代码可视化颜色栏部分。
fig.subplots_adjust(bottom=0.1, top=0.9, left=0.1, right=0.8,
wspace=0.4, hspace=0.1)
cb_ax = fig.add_axes([0.83, 0.1, 0.02, 0.8])
cbar = fig.colorbar(mesh, cax=cb_ax)
P.S.
聚苯乙烯
I would suggest using pcolormeshinstead of pcolorbecause it is faster (more infos here).
我建议使用pcolormesh而不是pcolor因为它更快(更多信息在这里)。


