简体   繁体   English

如何为python中的一系列图创建标准颜色条

[英]How can I create a standard colorbar for a series of plots in python

I using matplotlib to plot some data in python and the plots require a standard colour bar.我使用 matplotlib 在 python 中绘制一些数据,并且这些图需要一个标准的颜色条。 The data consists of a series of NxM matrices containing frequency information so that a simple imshow() plot gives a 2D histogram with colour describing frequency.数据由一系列包含频率信息的 NxM 矩阵组成,因此简单的 imshow() 图给出了带有颜色描述频率的 2D 直方图。 Each matrix contains data in different, but overlapping ranges.每个矩阵包含不同但重叠范围的数据。 Imshow normalizes the data in each matrix to the range 0-1 which means that, for example, the plot of matrix A, will appear identical to the plot of the matrix 2*A (though the colour bar will show double the values). Imshow 将每个矩阵中的数据归一化到 0-1 范围内,这意味着,例如,矩阵 A 的图与矩阵 2*A 的图看起来相同(尽管颜色条将显示两倍的值)。 What I would like is for the colour red, for example, to correspond to the same frequency in all of the plots.例如,我想要的是红色对应于所有图中的相同频率。 In other words, a single colour bar would suffice for all the plots.换句话说,一个颜色条就足以满足所有的情节。 Any suggestions would be greatly appreciated.任何建议将不胜感激。

Not to steal @ianilis's answer, but I wanted to add an example...不是窃取@ianilis 的答案,但我想添加一个示例...

There are multiple ways, but the simplest is just to specify the vmin and vmax kwargs to imshow .有多种方法,但最简单的方法是将vminvmax kwargs 指定给imshow Alternately, you can make a matplotlib.cm.Colormap instance and specify it, but that's more complicated than necessary for simple cases.或者,您可以创建一个matplotlib.cm.Colormap实例并指定它,但这对于简单情况来说比必要的要复杂。

Here's a quick example with a single colorbar for all images:这是一个快速示例,所有图像都有一个颜色条:

import numpy as np
import matplotlib.pyplot as plt

# Generate some data that where each slice has a different range
# (The overall range is from 0 to 2)
data = np.random.random((4,10,10))
data *= np.array([0.5, 1.0, 1.5, 2.0])[:,None,None]

# Plot each slice as an independent subplot
fig, axes = plt.subplots(nrows=2, ncols=2)
for dat, ax in zip(data, axes.flat):
    # The vmin and vmax arguments specify the color limits
    im = ax.imshow(dat, vmin=0, vmax=2)

# Make an axis for the colorbar on the right side
cax = fig.add_axes([0.9, 0.1, 0.03, 0.8])
fig.colorbar(im, cax=cax)

plt.show()

在此处输入图片说明

最简单的解决方案是为每个图使用相同的参数调用 clim(lower_limit, upper_limit)。

This only answer half of the question, or rather starts a new one.这只能回答一半的问题,或者更确切地说是开始一个新的问题。 If you change如果你改变

data *= np.array([0.5, 1.0, 1.5, 2.0])[:,None,None]

to

data *= np.array([2.0, 1.0, 1.5, 0.5])[:,None,None]

your colorbar will go from 0 to 0.5 which in this case is dark blue to slightly lighter blue and will not cover the whole range (0 to 2).您的颜色条将从 0 到 0.5,在这种情况下是深蓝色到略浅的蓝色,并且不会覆盖整个范围(0 到 2)。 The colorbar will only show the colors from the last image or contour regardless of vmin and vmax .无论vminvmax什么,颜色条都只会显示最后一个图像或轮廓的颜色。

I wasn't happy with the solutions that suggested to manually set vmin and vmax , so I decided to read the limits of each plot and automatically set vmin and vmax .我对建议手动设置vminvmax的解决方案不满意,所以我决定阅读每个图的限制并自动设置vminvmax

The example below shows three plots of samples taken from normal distributions with increasing mean value.下面的示例显示了从平均值增加的正态分布中提取的三个样本图。

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid
import numpy as np

numberOfPlots = 3
data = []
for i in range(numberOfPlots):
    mean = i
    data.append(np.random.normal(mean, size=(100,100)))

fig = plt.figure()
grid = ImageGrid(fig, 111, nrows_ncols=(1,numberOfPlots), cbar_mode='single')
ims = []
for i in range(numberOfPlots):
    ims.append(grid[i].imshow(data[i]))
    grid[i].set_title("Mean = " + str(i))

clims = [im.get_clim() for im in ims]
vmin = min([clim[0] for clim in clims])
vmax = max([clim[1] for clim in clims])
for im in ims:
    im.set_clim(vmin=np.floor(vmin),vmax=np.ceil(vmax))
grid[0].cax.colorbar(ims[0]) # with cbar_mode="single", cax attribute of all axes are identical    

fig.show()

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM