[英]How can I create custom break points in a matplotlib colorbar?
I'm borrowing an example from the matplotlib custom cmap examples page: 我从matplotlib自定义cmap示例页面借用了一个示例:
https://matplotlib.org/examples/pylab_examples/custom_cmap.html https://matplotlib.org/examples/pylab_examples/custom_cmap.html
This produces the same image with different numbers of shading contours, as specified in the number of bins: n_bins
: 如bins数中指定的那样,这将产生具有不同数量的阴影轮廓的同一图像:
n_bins
:
https://matplotlib.org/_images/custom_cmap_00.png https://matplotlib.org/_images/custom_cmap_00.png
However, I'm interested not only in the number of bins, but the specific break points between the color values. 但是,我不仅对垃圾箱的数量感兴趣,而且对颜色值之间的特定断点感兴趣。 For example, when
nbins=6
in the top right subplot, how can I specify the ranges of the bins to such that the shading is filled in these custom areas: 例如,当右上角子图中的
nbins=6
时,如何指定垃圾箱的范围,以便在这些自定义区域中填充阴影:
n_bins_ranges = ([-10,-5],[-5,-2],[-2,-0.5],[-0.5,2.5],[2.5,7.5],[7.5,10])
Is it also possible to specify the inclusivity of the break points? 是否还可以指定断点的包容性? For example, I'd like to specify in the range between -2 and 0.5 whether it's
-2 < x <= -0.5
or -2 <= x < -0.5
. 例如,我想在-2到0.5之间指定
-2 < x <= -0.5
或-2 <= x < -0.5
。
EDIT WITH ANSWER BELOW: 使用下面的答案进行编辑:
Using the accepted answer below, here is code that plots each step including finally adding custom colorbar ticks at the midpoint. 使用下面接受的答案,这是绘制每个步骤的代码,包括最终在中点添加自定义颜色条刻度。 Note I can't post an image since I'm a new user.
请注意,由于我是新用户,因此无法发布图片。
Set up data and 6 color bins: 设置数据和6个颜色档:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
# Make some illustrative fake data:
x = np.arange(0, np.pi, 0.1)
y = np.arange(0, 2*np.pi, 0.1)
X, Y = np.meshgrid(x, y)
Z = np.cos(X) * np.sin(Y) * 10
# Create colormap with 6 discrete bins
colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1)] # R -> G -> B
n_bin = 6
cmap_name = 'my_list'
cm = matplotlib.colors.LinearSegmentedColormap.from_list(
cmap_name, colors, N=n_bin)
Plot different options: 绘制不同的选项:
# Set up 4 subplots
fig, axs = plt.subplots(2, 2, figsize=(6, 9))
fig.subplots_adjust(left=0.02, bottom=0.06, right=0.95, top=0.94, wspace=0.05)
# Plot 6 bin figure
im = axs[0,0].imshow(Z, interpolation='nearest', origin='lower', cmap=cm)
axs[0,0].set_title("Original 6 Bin")
fig.colorbar(im, ax=axs[0,0])
# Change the break points
n_bins_ranges = [-10,-5,-2,-0.5,2.5,7.5,10]
norm = matplotlib.colors.BoundaryNorm(n_bins_ranges, len(n_bins_ranges))
im = axs[0,1].imshow(Z, interpolation='nearest', origin='lower', cmap=cm, norm=norm)
axs[0,1].set_title("Custom Break Points")
fig.colorbar(im, ax=axs[0,1])
# Arrange color labels by data interval (not colors)
im = axs[1,0].imshow(Z, interpolation='nearest', origin='lower', cmap=cm, norm=norm)
axs[1,0].set_title("Linear Color Distribution")
fig.colorbar(im, ax=axs[1,0], spacing="proportional")
# Provide custom labels at color midpoints
# And change inclusive equality by adding arbitrary small value
n_bins_ranges_arr = np.asarray(n_bins_ranges)+1e-9
norm = matplotlib.colors.BoundaryNorm(n_bins_ranges, len(n_bins_ranges))
n_bins_ranges_midpoints = (n_bins_ranges_arr[1:] + n_bins_ranges_arr[:-1])/2.0
im = axs[1,1].imshow(Z, interpolation='nearest', origin='lower', cmap=cm ,norm=norm)
axs[1,1].set_title("Midpoint Labels\n Switched Equal Sign")
cbar=fig.colorbar(im, ax=axs[1,1], spacing="proportional",
ticks=n_bins_ranges_midpoints.tolist())
cbar.ax.set_yticklabels(['Red', 'Brown', 'Green 1','Green 2','Gray Blue','Blue'])
plt.show()
You can use a BoundaryNorm
as follows: 您可以按如下方式使用
BoundaryNorm
:
import matplotlib.pyplot as plt
import matplotlib.colors
import numpy as np
x = np.arange(0, np.pi, 0.1)
y = np.arange(0, 2*np.pi, 0.1)
X, Y = np.meshgrid(x, y)
Z = np.cos(X) * np.sin(Y) * 10
colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1)] # R -> G -> B
n_bin = 6 # Discretizes the interpolation into bins
n_bins_ranges = [-10,-5,-2,-0.5,2.5,7.5,10]
cmap_name = 'my_list'
fig, ax = plt.subplots()
# Create the colormap
cm = matplotlib.colors.LinearSegmentedColormap.from_list(
cmap_name, colors, N=n_bin)
norm = matplotlib.colors.BoundaryNorm(n_bins_ranges, len(n_bins_ranges))
# Fewer bins will result in "coarser" colomap interpolation
im = ax.imshow(Z, interpolation='nearest', origin='lower', cmap=cm, norm=norm)
ax.set_title("N bins: %s" % n_bin)
fig.colorbar(im, ax=ax)
plt.show()
Or, if you want proportional spacing, ie the distance between colors according to their values, 或者,如果您想要比例间距,即根据颜色值之间的距离,
fig.colorbar(im, ax=ax, spacing="proportional")
As the boundary norm documentation states 正如边界规范文档所述
If
b[i] <= v < b[i+1]
then v is mapped to color j;如果
b[i] <= v < b[i+1]
则v映射到颜色j; as i varies from 0 to len(boundaries)-2, j goes from 0 to ncolors-1.当我从0变到len(boundaries)-2时,j从0变到ncolors-1。
So the colors are always chosen as -2 <= x < -0.5
, in order to obtain the equal sign on the other side you would need to supply something like n_bins_ranges = np.array([-10,-5,-2,-0.5,2.5,7.5,10])-1e-9
因此,颜色总是选择为
-2 <= x < -0.5
,为了获得另一侧的等号,您需要提供类似n_bins_ranges = np.array([-10,-5,-2,-0.5,2.5,7.5,10])-1e-9
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.