python - 两个子图上的两个颜色条,相同的图形

标签 python matplotlib plot data-visualization colorbar

我正在尝试制作一个包含两个子图的 matplotlib 图,以及每个子图右侧的一个颜色条。这是我目前的代码:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from mpl_toolkits.axes_grid1 import make_axes_locatable

X = tsne_out[:,0]
Y = tsne_out[:,1]
Z = tsne_out[:,2]

fig = plt.figure(figsize = (20,15))
ax1 = fig.add_subplot(221)
ax1.scatter(X, Y, c = material, s = df['Diameter (nm)']/4, cmap = plt.get_cmap('nipy_spectral', 11))
ax1.set_title("2D Representation", fontsize = 18)
ax1.set_xlabel("TSNE1", fontsize = 14)
ax1.set_ylabel("TSNE2", fontsize = 14)
ax1.set_xlim(-20,20)
ax1.set_ylim(-20,20)
ax1.set_xticks(list(range(-20,21,10)))
ax1.set_yticks(list(range(-20,21,10)))


cbar = fig.colorbar(cax, ticks=list(range(0,9)))
cbar.ax.tick_params(labelsize=15) 
cbar.ax.set_yticklabels(custom_ticks)  # horizontal colorbar


ax2 = fig.add_subplot(222, projection='3d')
ax2.scatter(X, Y, Z, c = material, s = df['Diameter (nm)']/4, cmap = plt.get_cmap('nipy_spectral', 11))
ax2.set_title("3D Representation", fontsize = 18)
ax2.set_xlabel("TSNE1", fontsize = 14)
ax2.set_ylabel("TSNE2", fontsize = 14)
ax2.set_zlabel("TSNE3", fontsize = 14)
ax2.set_xlim(-20,20)
ax2.set_ylim(-20,20)
ax2.set_zlim(-20,20)
ax2.set_xticks(list(range(-20,21,10)))
ax2.set_yticks(list(range(-20,21,10)))
ax2.set_zticks(list(range(-20,21,10)))

cbar = fig.colorbar(cax, ticks = list(range(0,9)))
cbar.ax.tick_params(labelsize=15) 
cbar.ax.set_yticklabels(custom_ticks)

这提供了下图: Matplotlib produced figure

我的问题是:为什么第一个颜色条不显示我的自定义刻度以及如何解决此问题?

最佳答案

问题似乎是 ScalarMappable对象似乎最多可以有一个与其关联的颜色条。当您使用相同的 ScalarMappable 绘制第二个颜色条时,原始颜色条将取消链接,并且第一个颜色条之前的设置将丢失。

您的代码缺少一些细节(特别是 cax 的定义),因此您要么必须创建两个单独的可映射对象,要么直接使用每个 scatter 调用的内容给你。此外,我会明确说明您想要将颜色条插入到哪里。

一个示例修复,假设 cax 实际上是指您的散点图:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

X = np.random.rand(100) * 40 - 20
Y = np.random.rand(100) * 40 - 20
Z = np.random.rand(100) * 40 - 20
C = np.random.randint(1,8,100)
custom_ticks = list('ABCDEFGH')

fig = plt.figure(figsize = (20,15))
ax1 = fig.add_subplot(121)
sc1 = ax1.scatter(X, Y, c = C, cmap='viridis') # use this mappable
ax1.set_title("2D Representation", fontsize = 18)
ax1.set_xlabel("TSNE1", fontsize = 14)
ax1.set_ylabel("TSNE2", fontsize = 14)
ax1.set_xlim(-20,20)
ax1.set_ylim(-20,20)
ax1.set_xticks(list(range(-20,21,10)))
ax1.set_yticks(list(range(-20,21,10)))


cbar = fig.colorbar(sc1, ax=ax1, ticks=list(range(0,9))) # be explicit about ax1
cbar.ax.tick_params(labelsize=15) 
cbar.ax.set_yticklabels(custom_ticks)

ax2 = fig.add_subplot(122, projection='3d')
sc2 = ax2.scatter(X, Y, Z, c=C, cmap='viridis') # next time use this one
ax2.set_title("3D Representation", fontsize = 18)
ax2.set_xlabel("TSNE1", fontsize = 14)
ax2.set_ylabel("TSNE2", fontsize = 14)
ax2.set_zlabel("TSNE3", fontsize = 14)
ax2.set_xlim(-20,20)
ax2.set_ylim(-20,20)
ax2.set_zlim(-20,20)
ax2.set_xticks(list(range(-20,21,10)))
ax2.set_yticks(list(range(-20,21,10)))
ax2.set_zticks(list(range(-20,21,10)))

cbar = fig.colorbar(sc2, ax=ax2, ticks=list(range(0,9))) # sc1 here is the bug
cbar.ax.tick_params(labelsize=15) 
cbar.ax.set_yticklabels(custom_ticks)

plt.show()

这会产生以下结果:

created figure, fixed colorbar

请注意,我创建了一个 MCVE为了你,我简化了一些事情,例如子图的数量。重点是颜色条设置现在保留,因为它们使用单​​独的可映射对象。

<小时/>

另一个选择是先创建颜色条(如果需要,可以使用相同的 ScalarMappable),然后再自定义:

sc = ax1.scatter(X, Y, c = C, cmap='viridis')
cbar1 = fig.colorbar(sc, ax=ax1, ticks=np.arange(0,9))
ax2.scatter(X, Y, Z, c=C, cmap='viridis')
cbar2 = fig.colorbar(sc, ax=ax2, ticks=np.arange(0,9)) # sc here too

for cbar in cbar1,cbar2:
    cbar.ax.tick_params(labelsize=15) 
    cbar.ax.set_yticklabels(custom_ticks)

上述工作的事实可能表明原始行为是一个错误。

关于python - 两个子图上的两个颜色条,相同的图形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50938167/

相关文章:

python - del语句是否打开内存?

python - 如何更正确地近似点

python - 使用 sympy 计算条件概率

python - 如果 k 是空列表,k[ :0] means, 会做什么

python - 文件未在 AWS Elastic Mapreduce 上缓存

python - 如何在 python Seaborn 中更改调色板中标签的颜色分配?

python - 具有 2 列的条形图

Matlab 在不重新绘制的情况下更改绘图中的单个点

matlab - 匹配轴刻度

matlab - 绘制一条粗细不同的线