Наложение графиков на один график

1

У меня есть две карты тепла, которые основаны на 2d гистограммах, которые я пытаюсь наложить на один граф. Пределы их осей (length_L и extent_H) не обязательно совпадают точно. Я могу сделать отдельные сюжеты удовлетворительными, если это необходимо, но при попытке показать оба тепломашины на одном графике красиво, отображается только самая последняя.

import numpy as np
import numpy.random
import matplotlib.pyplot as plt

# Generate some test data
x_L = np.random.randn(8873)
y_L = np.random.randn(8873)

x_H = np.random.randn(1000)
y_H = np.random.randn(1000)

heatmap_L, xedges_L, yedges_L = np.histogram2d(x_L, y_L, bins=50)
extent_L = [xedges_L[0], xedges_L[-1], yedges_L[0], yedges_L[-1]]

heatmap_H, xedges_H, yedges_H = np.histogram2d(x_H, y_H, bins=50)
extent_H = [xedges_H[0], xedges_H[-1], yedges_H[0], yedges_H[-1]]

plt.clf()
im1 = plt.imshow(heatmap_L.T, extent=extent_L, origin='lower', cmap='Blues')
im2 = plt.imshow(heatmap_H.T, extent=extent_H, origin='lower', cmap='Greens')
plt.show() 

Изображение 174551

Изменение: если я не ошибаюсь, все точки находятся не в правильном месте

import numpy as np
import numpy.random
import matplotlib.pyplot as plt

# Generate some test data
x_L = np.random.randn(8873)
y_L = np.random.randn(8873)

x_H = np.random.randn(1000)
y_H = np.random.randn(1000)

heatmap_L, xedges_L, yedges_L = np.histogram2d(x_L, y_L, bins=50)
extent_L = np.array([xedges_L[0], xedges_L[-1], yedges_L[0], yedges_L[-1]])

heatmap_H, xedges_H, yedges_H = np.histogram2d(x_H, y_H, bins=50)
extent_H = np.array([xedges_H[0], xedges_H[-1], yedges_H[0], yedges_H[-1]])

plt.clf()
im1 = plt.imshow(heatmap_L.T, extent=extent_L, origin='lower', cmap='Blues')
im2 = plt.imshow(heatmap_H.T, extent=extent_H, origin='lower', cmap='Greens')
plt.autoscale()
plt.show()

Изображение 174551

flatHMH = np.reshape(heatmap_H, 2500)  # flatten the 2D arrays
flatHML = np.reshape(heatmap_L, 2500)
maxHMH = flatHMH.max()  # Find the maximum in each
maxHML = flatHML.max()
# Now for each value in the flat array build an RGBA tuple using 
# 1 for the colour we want - either green or blue, and then scaling
# the value by the maximum, finally reshaping back to a 50x50 array
augHMH = np.array([(0, 1, 0, x/maxHMH) for x in flatHMH]).reshape((50, 50, 4))
augHML = np.array([(0, 0, 1, x/maxHML) for x in flatHML]).reshape((50, 50, 4))

plt.clf()
# Plot without cmap as colours are now part of the data array passed.
im1 = plt.imshow(augHML, extent=extent_L, origin='lower')
im2 = plt.imshow(augHMH, extent=extent_H, origin='lower')
plt.autoscale()
plt.show()

Изображение 174551

Если вы внимательно посмотрите на точки на последнем графике, например, кластеризацию точек на краю, вы заметите, что они не совпадают с приведенным выше графиком.

  • 0
    @ImportanceOfBeingErnest Буквально следует этому примеру , который предоставляет рабочий пример для случая одного графика. Я заинтересован в наложении двух таких сюжетов.
Теги:
matplotlib
histogram
heatmap
imshow

2 ответа

1
Лучший ответ

Вы показываете обе графики, проблема в том, что вы рисуете один поверх другого. Чтобы увидеть это в действии, вы можете перенести один из участков, как в:

import numpy as np
import numpy.random
import matplotlib.pyplot as plt

# Generate some test data
x_L = np.random.randn(8873)
y_L = np.random.randn(8873)

x_H = np.random.randn(1000)
y_H = np.random.randn(1000)

heatmap_L, xedges_L, yedges_L = np.histogram2d(x_L, y_L, bins=50)
extent_L = np.array([xedges_L[0], xedges_L[-1], yedges_L[0], yedges_L[-1]])

heatmap_H, xedges_H, yedges_H = np.histogram2d(x_H, y_H, bins=50)
extent_H = np.array([xedges_H[0], xedges_H[-1], yedges_H[0], yedges_H[-1]])

plt.clf()
im1 = plt.imshow(heatmap_L.T, extent=extent_L, origin='lower', cmap='Blues')
im2 = plt.imshow(heatmap_H.T+2, extent=extent_H+2, origin='lower', cmap='Greens')
plt.autoscale()
plt.show() 

Вам также нужен plt.autoscale() как в противном случае пределы не будут правильно настроены.

Один из способов показать две графики друг на друга - использовать аргумент alpha=X для вызова imshow (где 0 <X <1), чтобы установить прозрачность вызова сюжета. Другой, возможно, более ясный способ - преобразовать каждое значение из гистограммы2D в значение RGBA. См. Документы imshow для обеих альтернатив для отображения графиков друг на друге.

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

# imports and test data generation as before, removed for clarity...

flatHMH = np.reshape(heatmap_H, 2500)  # flatten the 2D arrays
flatHML = np.reshape(heatmap_L, 2500)
maxHMH = flatHMH.max()  # Find the maximum in each
maxHML = flatHML.max()
# Now for each value in the flat array build an RGBA tuple using 
# 1 for the colour we want - either green or blue, and then scaling
# the value by the maximum, finally reshaping back to a 50x50 array
augHMH = np.array([(0, 1, 0, x/maxHMH) for x in flatHMH]).reshape((50, 50, 4))
augHML = np.array([(0, 0, 1, x/maxHML) for x in flatHML]).reshape((50, 50, 4))

plt.clf()
# Plot without cmap as colours are now part of the data array passed.
im1 = plt.imshow(augHML, extent=extent_L, origin='lower')
im2 = plt.imshow(augHMH, extent=extent_H, origin='lower')
plt.autoscale()
plt.show() 
  • 0
    Да, альфа помогает в смешивании, но если оно слишком низкое, тогда оно кажется полностью размытым без четкого различия концентрированных точек. Но если альфа слишком высока, то прямоугольная сетка от каждого наложенного графика становится очень заметной. Есть ли оптимальный способ смешать фоны наложенных графиков, сохраняя заметные точки концентрации?
  • 0
    @ Mathews24, см. Обновленный ответ для альтернативного решения, о котором говорилось ранее в документации по imshow.
Показать ещё 1 комментарий
0

Ты можешь позвонить

plt.autoscale()

так что пределы корректируются с учетом содержания осей.

Пример:

import numpy as np
import matplotlib.pyplot as plt

def get(offs=0):
    # Generate some test data
    x = np.random.randn(8873)+offs
    y = np.random.randn(8873)+offs

    heatmap, xedges, yedges = np.histogram2d(x, y, bins=50)
    extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]

    heatmap, xedges, yedges = np.histogram2d(x, y, bins=50)
    extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
    return heatmap, extent

h1,e1  = get(-3)
h2,e2  = get(+3)
plt.imshow(h1, extent=e1, origin='lower', cmap="RdBu")
plt.imshow(h2, extent=e2, origin='lower', cmap="YlGnBu")
plt.autoscale()
plt.show()

Изображение 174551

  • 0
    Спасибо. Я проверил это, но не могу наложить графики, чтобы подтвердить, если они обязательно скорректированы как задумано.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню