Создание линейно-линейного графика в matplotlib с использованием hist2d

Мне просто интересно, можно ли это сделать. Я попытался установить корзины явно, используя пустое пространство журнала, и я также попытался установить xscale на "log". Ни один из этих вариантов не работает. Кто-нибудь когда-нибудь пробовал это?

Мне просто нужна двумерная гистограмма с лог-осью X и линейной осью Y.

1 ответ

Решение

Причина, по которой он работает неправильно, заключается в том, что plt.hist2d использует pcolorfast метод, который намного более эффективен для больших изображений, но не поддерживает оси журналов.

Чтобы иметь двухмерную гистограмму, которая корректно работает на осях бревен, вам нужно сделать ее самостоятельно, используя np.histogram2d а также ax.pcolor, Однако это всего лишь одна дополнительная строка кода.

Для начала давайте используем экспоненциально разнесенные ячейки на линейной оси:

import numpy as np
import matplotlib.pyplot as plt

x, y = np.random.random((2, 1000))
x = 10**x

xbins = 10**np.linspace(0, 1, 10)
ybins = np.linspace(0, 1, 10)

fig, ax = plt.subplots()
ax.hist2d(x, y, bins=(xbins, ybins))

plt.show()

Ладно все хорошо. Давайте посмотрим, что произойдет, если мы сделаем так, чтобы ось X использовала логарифмический масштаб:

import numpy as np
import matplotlib.pyplot as plt

x, y = np.random.random((2, 1000))
x = 10**x

xbins = 10**np.linspace(0, 1, 10)
ybins = np.linspace(0, 1, 10)

fig, ax = plt.subplots()
ax.hist2d(x, y, bins=(xbins, ybins))

ax.set_xscale('log') # <-- Only difference from previous example

plt.show()

Обратите внимание, что масштабирование логов, кажется, применено, но цветное изображение (гистограмма) не отражает его. Контейнеры должны быть квадратными! Они не потому, что художник, созданный pcolorfast не поддерживает оси журналов.

Чтобы это исправить, давайте сделаем гистограмму, используя np.histogram2d (какие plt.hist2d использует закулисные), а затем подготовить pcolormesh (или же pcolor), который поддерживает лог-оси:

import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1977)

x, y = np.random.random((2, 1000))
x = 10**x

xbins = 10**np.linspace(0, 1, 10)
ybins = np.linspace(0, 1, 10)

counts, _, _ = np.histogram2d(x, y, bins=(xbins, ybins))

fig, ax = plt.subplots()
ax.pcolormesh(xbins, ybins, counts.T)

ax.set_xscale('log')

plt.show()

(Обратите внимание, что мы должны транспонировать counts здесь, потому что pcolormesh ожидает, что оси будут в порядке (Y, X).)

Теперь мы получаем ожидаемый результат:

Другие вопросы по тегам