Перед тем, как начать, я хочу сказать, что я пытался выполнить этот и этот пост по той же проблеме, однако они делают это с тепловыми картами imshow в отличие от 2d гистограммы, как я 'я делаю.
Вот мой код (фактические данные были заменены случайно сгенерированными данными, но суть та же):
import matplotlib.pyplot as plt
import numpy as np
def subplots_hist_2d(x_data, y_data, x_labels, y_labels, titles):
fig, a = plt.subplots(2, 2)
a = a.ravel()
for idx, ax in enumerate(a):
image = ax.hist2d(x_data[idx], y_data[idx], bins=50, range=[[-2, 2],[-2, 2]])
ax.set_title(titles[idx], fontsize=12)
ax.set_xlabel(x_labels[idx])
ax.set_ylabel(y_labels[idx])
ax.set_aspect("equal")
cb = fig.colorbar(image[idx])
cb.set_label("Intensity", rotation=270)
# pad = how big overall pic is
# w_pad = how separate they're left to right
# h_pad = how separate they're top to bottom
plt.tight_layout(pad=-1, w_pad=-10, h_pad=0.5)
x1, y1 = np.random.uniform(-2, 2, 10000), np.random.uniform(-2, 2, 10000)
x2, y2 = np.random.uniform(-2, 2, 10000), np.random.uniform(-2, 2, 10000)
x3, y3 = np.random.uniform(-2, 2, 10000), np.random.uniform(-2, 2, 10000)
x4, y4 = np.random.uniform(-2, 2, 10000), np.random.uniform(-2, 2, 10000)
x_data = [x1, x2, x3, x4]
y_data = [y1, y2, y3, y4]
x_labels = ["x1", "x2", "x3", "x4"]
y_labels = ["y1", "y2", "y3", "y4"]
titles = ["1", "2", "3", "4"]
subplots_hist_2d(x_data, y_data, x_labels, y_labels, titles)
И это то, что он генерирует:
Так что теперь моя проблема в том, что я не могу на всю жизнь заставить цветовую панель применить ко всем 4 гистограммам.Также по какой-то причине нижняя правая гистограмма ведет себя странно по сравнению с другими.В ссылках, которые я разместил, их методы, по-видимому, не используют a = a.ravel()
, и я использую его только здесь, потому что это единственный способ, который позволяет мне отображать мои 4 гистограммы в качестве вспомогательных участков.Помогите?
РЕДАКТИРОВАТЬ: Томас Кун, ваш новый метод фактически решил все мои проблемы, пока я не положил свои ярлыки и попытался использовать plt.tight_layout()
, чтобы разобраться в перекрытиях.Кажется, что если я запишу определенные параметры в plt.tight_layout(pad=i, w_pad=0, h_pad=0)
, то цветовая полоса начнет плохо себя вести.Теперь я объясню свою проблему.
Я внес некоторые изменения в ваш новый метод, чтобы он соответствовал тому, что я хочу, например:
def test_hist_2d(x_data, y_data, x_labels, y_labels, titles):
nrows, ncols = 2, 2
fig, axes = plt.subplots(nrows, ncols, sharex=True, sharey=True)
##produce the actual data and compute the histograms
mappables=[]
for (i, j), ax in np.ndenumerate(axes):
H, xedges, yedges = np.histogram2d(x_data[i][j], y_data[i][j], bins=50, range=[[-2, 2],[-2, 2]])
ax.set_title(titles[i][j], fontsize=12)
ax.set_xlabel(x_labels[i][j])
ax.set_ylabel(y_labels[i][j])
ax.set_aspect("equal")
mappables.append(H)
##the min and max values of all histograms
vmin = np.min(mappables)
vmax = np.max(mappables)
##second loop for visualisation
for ax, H in zip(axes.ravel(), mappables):
im = ax.imshow(H,vmin=vmin, vmax=vmax, extent=[-2,2,-2,2])
##colorbar using solution from linked question
fig.colorbar(im,ax=axes.ravel())
plt.show()
# plt.tight_layout
# plt.tight_layout(pad=i, w_pad=0, h_pad=0)
Теперь, если я попытаюсь сгенерировать свои данные, в данном случае:
phi, cos_theta = get_angles(runs)
detector_x1, detector_y1, smeared_x1, smeared_y1 = detection_vectorised(1.5, cos_theta, phi)
detector_x2, detector_y2, smeared_x2, smeared_y2 = detection_vectorised(1, cos_theta, phi)
detector_x3, detector_y3, smeared_x3, smeared_y3 = detection_vectorised(0.5, cos_theta, phi)
detector_x4, detector_y4, smeared_x4, smeared_y4 = detection_vectorised(0, cos_theta, phi)
Здесь detector_x, detector_y, smeared_x, smeared_y
- все списки точек данных. Теперь я поместил их в списки 2x2
, чтобы их можно было распаковать соответствующим образом с помощью моей функции построения, например:
data_x = [[detector_x1, detector_x2], [detector_x3, detector_x4]]
data_y = [[detector_y1, detector_y2], [detector_y3, detector_y4]]
x_labels = [["x positions(m)", "x positions(m)"], ["x positions(m)", "x positions(m)"]]
y_labels = [["y positions(m)", "y positions(m)"], ["y positions(m)", "y positions(m)"]]
titles = [["0.5m from detector", "1.0m from detector"], ["1.5m from detector", "2.0m from detector"]]
Теперь я запускаю свой код с
test_hist_2d(data_x, data_y, x_labels, y_labels, titles)
при включенном plt.show()
, это дает:

, что замечательно, потому что с точки зрения данных и визуального представления это именно то, что я хочу, т.е. цветовая карта соответствует всем 4 гистограммам.Однако, поскольку метки перекрываются с названиями, я подумал, что просто запустил бы то же самое, но на этот раз с plt.tight_layout(pad=a, w_pad=b, h_pad=c)
, надеясь, что смогу решить проблему с перекрывающимися метками.Однако на этот раз не имеет значения, как я изменяю числа a, b
и c
, я всегда получаю свою цветную полосу, лежащую на втором столбце графиков, например:

Теперь изменение a
только увеличивает или уменьшает общие подзаговоры, и лучшее, что я мог сделать, это настроить его с помощью plt.tight_layout(pad=-10, w_pad=-15, h_pad=0)
, который выглядит следующим образом

Таким образом, кажется, что независимо от того, что делает ваш новый метод, он заставил весь график потерять свою настраиваемость.Ваше решение, столь же прекрасное, как и решение одной проблемы, взамен создало другую.Так что было бы лучше всего сделать здесь?
Редактировать 2:
Используя fig, axes = plt.subplots(nrows, ncols, sharex=True, sharey=True, constrained_layout=True)
вместе с plt.show() gives

Как вы можете видеть, между столбцами вспомогательных участков все еще есть вертикальный разрыв, от которого даже с помощью plt.subplots_adjust()
можно избавиться.