扩展颜色条以包含超出范围的数据

Extending colorbar to include out of range data

我正在尝试使用以下代码制作极地热图。

# Plotting the polar plot 
from matplotlib.colorbar import ColorbarBase
from matplotlib.colors import LogNorm
import matplotlib.pyplot as plt
cmap = obspy_sequential 

# Have defined the variables to be used for pointing to the coordinates 
# baz is angular, slow is radial, abs_power is the value at every co-ordinate
# Choose number of fractions in plot (desirably 360 degree/N is an integer!)
N = 72
N2 = 30
abins = np.arange(N + 1) * 360. / N
sbins = np.linspace(0, 3, N2 + 1)

# Sum rel power in bins given by abins and sbins
hist, baz_edges, sl_edges = \
    np.histogram2d(baz, slow, bins=[abins, sbins], weights=abs_power)

# Transform to radian
baz_edges = np.radians(baz_edges)

# Add polar and colorbar axes
fig = plt.figure(figsize=(8, 8))
cax = fig.add_axes([0.85, 0.2, 0.05, 0.5])
ax = fig.add_axes([0.10, 0.1, 0.70, 0.7], polar=True)
ax.set_theta_direction(-1)
ax.set_theta_zero_location("N")

dh = abs(sl_edges[1] - sl_edges[0])
dw = abs(baz_edges[1] - baz_edges[0])

# Circle through backazimuth
for i, row in enumerate(hist):
    bars = ax.bar((i * dw) * np.ones(N2),
                  height=dh * np.ones(N2),
                  width=dw, bottom=dh * np.arange(N2),color=cmap(row / hist.max()))

ax.set_xticks(np.linspace(0, 2 * np.pi, 10, endpoint=False))
ax.set_yticklabels(velocity)
ax.set_ylim(0, 3)
[i.set_color('white') for i in ax.get_yticklabels()]
ColorbarBase(cax, cmap=cmap,
             norm=LogNorm(vmin=hist.min(),vmax=hist.max()))
plt.show()

我正在创建多个这样的图,因此我需要将颜色条的范围扩展到 abs_power 数据范围的最大值之外。 我尝试将 vmax 和 vmin 更改为我想要的最大最小目标数,但它每次都绘制出完全相同的图。颜色条上的最大值不断变化,但绘图没有变化。为什么会这样? 这是它的样子,



此处实际最大功率远小于颜色条中指定的最大值。仍然可以看到一个明亮的黄色斑点。 PS:对于我提供的任何 vmax、vmin 值,我都会得到相同的图。

更改颜色条不会影响主要情节。您需要更改 color=cmap(row / hist.max()) 中使用的公式才能更改条形图。 'norm' 就是为了这个任务。范数将数字的范围映射到区间[0, 1]。映射到大于 1 的值(即示例中大于 hist.max() 的值)的每个值都会分配最高颜色。

要让颜色条反映正确的信息,您需要对绘图和颜色条使用相同的 cmap 和相同的范数:

my_norm = LogNorm(vmin=hist.min(),vmax=hist.max())
for i, row in enumerate(hist):
    bars = ax.bar((i * dw) * np.ones(N2),
                  height=dh * np.ones(N2),
                  width=dw, bottom=dh * np.arange(N2),color=cmap(my_norm(row)))

ColorbarBase(cax, cmap=cmap, norm=my_norm)

另一方面,如果您不想显示黄色,您可以在上面的代码中尝试类似 my_norm = LogNorm(vmin=hist.min(), vmax=hist.max()*100) 的内容。

与其通过 ColorbarBase 创建颜色栏,不如使用标准 plt.colorbar(),但使用 ScalarMappable 指示颜色映射和使用的标准。在 LogNorm 的情况下,这将以日志格式显示报价。

from matplotlib.cm import ScalarMappable
plt.colorbar(ScalarMappable(cmap=cmap, norm=my_norm), ax=ax, cax=cax)