Создание линейно-линейного графика в 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).)
Теперь мы получаем ожидаемый результат: