如何在多个子图之间共享调色板?

How to shared color palette between multiple subplots?

我有下图:

该图由以下代码片段组成:

fig = plt.figure(constrained_layout=True)
grid = fig.add_gridspec(2, 2)

ax_samples_losses = fig.add_subplot(grid[0, 0:])
ax_samples_losses.set_title('Avg. loss per train sample (epoch 0 excluded)')
for sample_idx, sample_avg_train_loss_history in enumerate(samples_avg_train_loss_history):
    ax_samples_losses.plot(sample_avg_train_loss_history, label='Sample ' + str(sample_idx))
ax_samples_losses.set_title('Avg. loss per train sample (epoch 0 excluded)')
ax_samples_losses.set_xlabel('Epoch')
ax_samples_losses.set_ylabel('Sample avg. loss')
ax_samples_losses.set_xticks(range(1, epochs))
ax_samples_losses.tick_params(axis='x', rotation=90)
ax_samples_losses.yaxis.set_ticks(np.arange(0, np.max(samples_avg_train_loss_history), 0.25))
ax_samples_losses.tick_params(axis='both', which='major', labelsize=6)
plt.legend(bbox_to_anchor=(1, 1), prop={'size': 6}) #loc="upper left"
# fig.legend(...)

ax_patches_per_sample = fig.add_subplot(grid[1, 0])
#for sample_idx, sample_patches_count in enumerate(samples_train_patches_count):
#    ax_patches_per_sample.bar(sample_patches_count, label='Sample ' + str(sample_idx))
ax_patches_per_sample.bar(range(0, len(samples_train_patches_count)), samples_train_patches_count, align='center')
ax_patches_per_sample.set_title('Patches per sample')
ax_patches_per_sample.set_xlabel('Sample')
ax_patches_per_sample.set_ylabel('Patch count')
ax_patches_per_sample.set_xticks(range(0, len(samples_train_patches_count)))
ax_patches_per_sample.yaxis.set_ticks(np.arange(0, np.max(samples_train_patches_count), 20))
ax_patches_per_sample.tick_params(axis='both', which='major', labelsize=6)

哪里

我确实认为我需要两者都做

共享图例可以使用get_legend_handles_labels()完成。但是我不知道如何分享颜色。两个子图都描述了同一事物的不同属性 - 样本。简而言之,我希望每个样本 补丁 子图具有所有颜色 Avg。每个训练样本的损失(排除第 0 轮) 使用。

第一个图是使用标准的 matplotlib Tab10 离散色图。我们可以在这个颜色图上创建一个循环器,并一一设置每个条形的颜色:

import matplotlib.pyplot as plt
import matplotlib.cm as cm
from matplotlib.gridspec import GridSpec
import numpy as np
from itertools import cycle

# create a cycler to continously loop over a discrete colormap
cycler = cycle(cm.tab10.colors)

N = 10
x = np.arange(N).astype(int)
y = np.random.uniform(5, 15, N)

f = plt.figure()
gs = GridSpec(2, 4)
ax0 = f.add_subplot(gs[0, :-1])
ax1 = f.add_subplot(gs[1, :-1])
ax2 = f.add_subplot(gs[:, -1])

for i in x:
    ax0.plot(x, np.exp(-x / (i + 1)), label="Sample %s" % (i + 1))
h, l = ax0.get_legend_handles_labels()

ax1.bar(x, y)
for p in ax1.patches:
    p.set_facecolor(next(cycler))

ax2.axis(False)
ax2.legend(h, l)
plt.tight_layout()

编辑 以容纳评论。为避免重复,您应该使用颜色图。 Matplotlib 提供了许多 colormaps. Alternatively, you can also create your own.

import matplotlib.pyplot as plt
import matplotlib.cm as cm
from matplotlib.gridspec import GridSpec
import numpy as np
from itertools import cycle

N = 50
# create a cycler to continously loop over a discrete colormap
colors = cm.viridis(np.linspace(0, 1, N))

x = np.arange(N).astype(int)
y = np.random.uniform(5, 15, N)

f = plt.figure()
gs = GridSpec(2, 4)
ax0 = f.add_subplot(gs[0, :-1])
ax1 = f.add_subplot(gs[1, :-1])
ax2 = f.add_subplot(gs[:, -1])

ax1.bar(x, y)

for i in x:
    c = next(cycler)
    ax0.plot(x, np.exp(-x / (i + 1)), color=c, label="Sample %s" % (i + 1))
    ax1.patches[i].set_facecolor(c)
h, l = ax0.get_legend_handles_labels()

ax2.axis(False)
ax2.legend(h, l)
plt.tight_layout()