使散布颜色条仅显示vmin/vmax的一部分 [英] Make a scatter colorbar display only a subset of the vmin/vmax

查看:31
本文介绍了使散布颜色条仅显示vmin/vmax的一部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到一种情况,我想创建一个颜色栏,该颜色栏的颜色(与散点图相关)跨越特定范围,但只能在颜色栏本身上显示该范围的子集.我可以使用 contourf 做到这一点,因为我可以独立于轮廓线级别设置 vmin vmax ,但是我不知道如何做到分散.请参阅以下内容:

I have a situation where I want to create a colorbar whose colors (associated with a scatter plot) span a particular range, but only display a subset of that range on the colorbar itself. I can do it with contourf, because I can set vmin and vmax independently of the contour levels, but I can't figure out how to do it with scatter. See the following:

import numpy as np

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable

x = np.linspace(0, 2*np.pi, 101)
x_arr = np.sin(x)
y_arr = np.cos(x)
arr = y_arr[:,None] * x_arr[None,:]

arr = np.where(arr < 0, arr*4, arr)
ptslist = np.array([-4, -3, -2, -1, 0, 1], dtype=np.float32)

fig, axs = plt.subplots(figsize=(11,5), nrows=1, ncols=2)

# I can achieve my desired behavior with contourf
cont = axs[0].contourf(x, x, arr, levels=np.linspace(-4,1,11),
                       cmap='BrBG_r', vmin=-4, vmax=4)
div0 = make_axes_locatable(axs[0])
cax0 = div0.append_axes('right', '5%', '2%')
plt.colorbar(cont, cax=cax0)

# I can't make this colorbar do a similar thing
sc = axs[1].scatter(np.arange(-4, 2), np.arange(-4, 2), c=ptslist, cmap='BrBG_r',
                    marker='o', s=144, edgecolors='black', vmin=-4, vmax=4)
div1 = make_axes_locatable(axs[1])
cax1 = div1.append_axes('right', '5%', '2%')
cb = plt.colorbar(sc, cax=cax1)

得出以下数字:

我希望发散的颜色图以白色在0处居中,颜色值线性显示在零的两边.两个 plots 都能做到这一点.但是,我不希望从1到4的多余值显示在右侧的颜色栏上(请参阅左侧的颜色栏如何在1处停止).

I want the diverging colormap to be centered with white at zero, and the color values displayed linearly on both sides of zero. Both plots do this fine. However, I don't want the extra values from 1 to 4 to display on the right colorbar (see how the left colorbar stops at 1).

我的第一个念头是 ylim ,但是这一行:

My first thought was ylim, but this line:

cb.ax.set_ylim(-4, 1)

使这种奇怪的事情发生:

causes this strange thing to happen:

如果我使用 set_ticks ,它只会删除不存在的刻度线,并且不会更改限制.有什么办法可以很好地做到这一点?

If I use set_ticks, it just removes absent ticks, and doesn't change the limits. Is there any way to make this happen nicely?

我正在使用matplotlib 1.5.0.

I'm using matplotlib 1.5.0.

p.s.我还尝试了在SO上找到的以中点为中心的Normalize子类,但是它可以独立缩放正值和负值,这是我不希望的(它使+1.0暗褐色,我想要它仍然是浅棕色,除非我设置 vmax = 4 ,否则我有完全相同的问题.

p.s. I've also tried a mid-point-centered subclass of Normalize that I found on SO, but it scales the positive and negative values independently, which I don't want (it makes the values of +1.0 dark brown, and I want it to still be light brown, unless I set vmax=4, at which point I have exactly the same problem).

推荐答案

您可以将 boundaries 参数传递给 colorbar :

plt.colorbar(sc, cax=cax1, boundaries=sc.get_array())

我不知道 sc.get_array()是否始终是正确的选择,但是 get_array 是ScalarMappable方法,应该将数据获取为映射到颜色上,因此似乎是一个合理的选择.(对于轮廓集, colorbar 会自动获取轮廓级别并将其用作边界.)

I don't know whether sc.get_array() is always the right choice here, but get_array is the ScalarMappable method that is supposed to get the data to be mapped onto colors, so it seems like a reasonable choice. (For contour sets, colorbar automatically grabs the contour levels and uses them as the boundaries.)

这篇关于使散布颜色条仅显示vmin/vmax的一部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆