将颜色条作为图例添加到 matplotlib 散点图(多个子图,多个散点图)
Add colorbar as legend to matplotlib scatterplot (multiple subplots, multiple scatters)
我有几个子图要添加一个颜色条。每个子图由 7 个散点组成。我找到了关于如何添加颜色条的建议,但它们主要与每个散点的值有关,而不是与行本身有关。
代表性示例代码:
import numpy as np
from matplotlib import pyplot as plt
x = range(50)
scales = np.linspace(0, 2, 7)
locs = range(4)
cmap = plt.get_cmap("Spectral")
for s_plot in range(4):
plt.subplot(2, 2, s_plot+1)
color = iter(cmap(np.linspace(0, 1, len(scales))))
for scale in scales:
c = next(color)
y = np.random.normal(loc=locs[s_plot], scale=scale, size=50)
plt.scatter(x, y, c=c, s=5)
plt.title("Mean = {:d}".format(locs[s_plot]))
plt.subplots_adjust(hspace=0.4)
plt.show()
上面的例子给出了:
我想要的颜色条看起来像这样(假的,放在图旁边):
所以颜色条不描述我的散点的值,而是描述迭代的不同“行”(在这种情况下:不同的比例)。在有助于将点与比例匹配的示例中。
我尝试的是一个简单的
plt.colorbar()
完成每个子图后调用一次。但我明白了
TypeError: You must first set_array for mappable
另外,由于我想为其创建颜色图的比例不同,因此我也尝试了
plt.colorbar(scales)
哪个returns:AttributeError: 'numpy.ndarray' object has no attribute 'autoscale_None'
。
我目前对如何进行这件事缺乏方向。
编辑:我被标记为 matplotlib colorbar for scatter 的可能重复项。我已经找到了那个问题,但它对我的问题没有帮助。在我的例子中,我需要一个独立于 z 值的颜色图,但只会指示“行号”或“散点行”,或者你想如何称呼它(相当于 [=15 中的“行” =]).
如果我理解正确的话,那么你有一些范围并且想要为此绘制一个颜色图(没有一些图实际使用颜色图)。基本上你可以使用
在任何轴上绘制颜色图
import matplotlib
norm = matplotlib.colors.Normalize(vmin=0, vmax=50)
ax = plt.gca()
matplotlib.colorbar.ColorbarBase(ax, cmap='viridis', norm=norm)
您当然可以在其中使用任何坐标轴(或使用 inset_axes
将坐标轴放置在特定位置)。
更棘手的是首先为您的散点图获取与颜色图匹配的颜色。我不确定是否有更简单的方法,但我将颜色转换为 RGB 以进行绘图。这是一个完整的例子:
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
import numpy as np
N = 10
# dummy data
x_ = [k/10*np.arange(10) for k in range(N)]
cmap = matplotlib.cm.get_cmap('viridis')
cmap_values = np.linspace(0., 1., N)
colors = cmap(cmap_values)
colors_rgb = ['#{0:02x}{1:02x}{2:02x}'.format(int(255*a), int(255*b), int(255*c)) for a, b, c, _ in colors]
plt.figure()
for x, c in zip(x_, colors_rgb):
plt.plot(x, c=c)
norm = matplotlib.colors.Normalize(vmin=0, vmax=50)
ticks = np.arange(0, 60, 10)
# vertical colorbar
cbaxes = inset_axes(plt.gca(), width="3%", height="80%", loc=2)
cbar = matplotlib.colorbar.ColorbarBase(cbaxes, cmap=cmap, norm=norm, ticks=ticks)
cbar.set_label('scale')
cbar.ax.set_yticklabels(ticks, fontsize=12)
颜色条需要 ScalarMappable
作为输入。因此,如果您在情节中创建的 none 事物适合于此,您可以自己创建它。
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.cm import ScalarMappable
x = range(50)
scales = np.linspace(0, 2, 7)
locs = range(4)
cmap = plt.get_cmap("Spectral")
norm = plt.Normalize(scales.min(), scales.max())
fig, axes = plt.subplots(2,2, constrained_layout=True, sharey=True)
for s_plot, ax in enumerate(axes.flat):
for scale in scales:
y = np.random.normal(loc=locs[s_plot], scale=scale, size=50)
sc = ax.scatter(x, y, c=[cmap(norm(scale))], s=5)
ax.set_title("Mean = {:d}".format(locs[s_plot]))
sm = ScalarMappable(norm=norm, cmap=cmap)
sm.set_array([])
cbar = fig.colorbar(sm, ax=axes[:,1])
cbar.ax.set_title("scale")
plt.show()
我有几个子图要添加一个颜色条。每个子图由 7 个散点组成。我找到了关于如何添加颜色条的建议,但它们主要与每个散点的值有关,而不是与行本身有关。
代表性示例代码:
import numpy as np
from matplotlib import pyplot as plt
x = range(50)
scales = np.linspace(0, 2, 7)
locs = range(4)
cmap = plt.get_cmap("Spectral")
for s_plot in range(4):
plt.subplot(2, 2, s_plot+1)
color = iter(cmap(np.linspace(0, 1, len(scales))))
for scale in scales:
c = next(color)
y = np.random.normal(loc=locs[s_plot], scale=scale, size=50)
plt.scatter(x, y, c=c, s=5)
plt.title("Mean = {:d}".format(locs[s_plot]))
plt.subplots_adjust(hspace=0.4)
plt.show()
上面的例子给出了:
我想要的颜色条看起来像这样(假的,放在图旁边):
所以颜色条不描述我的散点的值,而是描述迭代的不同“行”(在这种情况下:不同的比例)。在有助于将点与比例匹配的示例中。
我尝试的是一个简单的
plt.colorbar()
完成每个子图后调用一次。但我明白了
TypeError: You must first set_array for mappable
另外,由于我想为其创建颜色图的比例不同,因此我也尝试了
plt.colorbar(scales)
哪个returns:AttributeError: 'numpy.ndarray' object has no attribute 'autoscale_None'
。
我目前对如何进行这件事缺乏方向。 编辑:我被标记为 matplotlib colorbar for scatter 的可能重复项。我已经找到了那个问题,但它对我的问题没有帮助。在我的例子中,我需要一个独立于 z 值的颜色图,但只会指示“行号”或“散点行”,或者你想如何称呼它(相当于 [=15 中的“行” =]).
如果我理解正确的话,那么你有一些范围并且想要为此绘制一个颜色图(没有一些图实际使用颜色图)。基本上你可以使用
在任何轴上绘制颜色图import matplotlib
norm = matplotlib.colors.Normalize(vmin=0, vmax=50)
ax = plt.gca()
matplotlib.colorbar.ColorbarBase(ax, cmap='viridis', norm=norm)
您当然可以在其中使用任何坐标轴(或使用 inset_axes
将坐标轴放置在特定位置)。
更棘手的是首先为您的散点图获取与颜色图匹配的颜色。我不确定是否有更简单的方法,但我将颜色转换为 RGB 以进行绘图。这是一个完整的例子:
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
import numpy as np
N = 10
# dummy data
x_ = [k/10*np.arange(10) for k in range(N)]
cmap = matplotlib.cm.get_cmap('viridis')
cmap_values = np.linspace(0., 1., N)
colors = cmap(cmap_values)
colors_rgb = ['#{0:02x}{1:02x}{2:02x}'.format(int(255*a), int(255*b), int(255*c)) for a, b, c, _ in colors]
plt.figure()
for x, c in zip(x_, colors_rgb):
plt.plot(x, c=c)
norm = matplotlib.colors.Normalize(vmin=0, vmax=50)
ticks = np.arange(0, 60, 10)
# vertical colorbar
cbaxes = inset_axes(plt.gca(), width="3%", height="80%", loc=2)
cbar = matplotlib.colorbar.ColorbarBase(cbaxes, cmap=cmap, norm=norm, ticks=ticks)
cbar.set_label('scale')
cbar.ax.set_yticklabels(ticks, fontsize=12)
颜色条需要 ScalarMappable
作为输入。因此,如果您在情节中创建的 none 事物适合于此,您可以自己创建它。
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.cm import ScalarMappable
x = range(50)
scales = np.linspace(0, 2, 7)
locs = range(4)
cmap = plt.get_cmap("Spectral")
norm = plt.Normalize(scales.min(), scales.max())
fig, axes = plt.subplots(2,2, constrained_layout=True, sharey=True)
for s_plot, ax in enumerate(axes.flat):
for scale in scales:
y = np.random.normal(loc=locs[s_plot], scale=scale, size=50)
sc = ax.scatter(x, y, c=[cmap(norm(scale))], s=5)
ax.set_title("Mean = {:d}".format(locs[s_plot]))
sm = ScalarMappable(norm=norm, cmap=cmap)
sm.set_array([])
cbar = fig.colorbar(sm, ax=axes[:,1])
cbar.ax.set_title("scale")
plt.show()