У меня есть записи n_series с одинаковыми кадрами 0, 1, 2, 3,... и я хотел бы сделать из них 2D-контур.
Я обнаружил, что могу очень легко сделать следующее:
import matplotlib.pyplot as plt
import numpy as np
series_len = 1000
n_series = 10
y = np.random.normal(0, 0.15, series_len * n_series)
x = np.tile(np.arange(0, series_len, 1), n_series)
heatmap, xbins, ybins = np.histogram2d(x, y, bins=20)
plt.contourf(heatmap.T)
plt.show()
Но поскольку это просто дает гистограмму 20x20, я понятия не имею, как мои интенсивности распределяются на выведенном графике (например, примерно с нулевым центром) и как исправить тики.
Как должны выглядеть ваши x тики?
Отредактировал основной пост. Надеюсь, теперь стало понятнее.
Попробуйте set_xticklabels
:
series_len = 1000
n_series = 10
fig, ax = plt.subplots(figsize=(10,6))
np.random.seed(1)
y = np.random.normal(0, 0.15, series_len * n_series)
x = np.tile(np.arange(0, series_len, 1), n_series)
heatmap, xs, ys = np.histogram2d(x, y, bins=20)
fig, ax = plt.subplots(figsize=(10,6))
ax.contourf(heatmap.T)
# the actual x-axis and y-axis are from 0 to 19
# we want to put 11 ticks on the axis
ax.set_xticks(np.linspace(0,19,11))
ax.set_xticklabels(range(0,1001,100))
ax.set_yticks(np.linspace(0,19,11))
ax.set_yticklabels(['{:.3f}'.format(y) for y in ys[::2]])
plt.show()
Выход:
Выглядит отлично! Но ммм... xticks не выстраиваются правильно, а это значит, что и yticks, вероятно, тоже.
Правда, проблема в том, что ваш heatmap
это 20x20
, поэтому по умолчанию ax
имеет 20
галочки на каждой оси, а xs
имеет 21 элемент, фиксируя
IIUC, вы хотели что-то вроде этого:
import matplotlib.pyplot as plt
import numpy as np
series_len = 1000
n_series = 10
y = np.random.normal(0, 0.15, series_len * n_series)
x = np.tile(np.arange(0, series_len, 1), n_series)
heatmap, xlabels, ylabels = np.histogram2d(x, y, bins=20)
plt.contourf(xlabels[:-1], ylabels[:-1], heatmap.T)
plt.colorbar()
plt.show()
Выход:
Почти, и действительно очень простое решение. Однако галочки выстроены неправильно, как вы увидите, если увеличите n_series
.
Хорошо, я сам нашел ответ, который делает процесс много проще, чем кажется. Просто измените размер тепловой карты на 1 в обоих направлениях, используя skimage
, и все будет хорошо следовать.
import matplotlib.pyplot as plt
import numpy as np
import skimage.transform
series_len = 1000
n_series = 10
bins = 20
y = np.random.normal(0, 0.15, series_len * n_series)
x = np.tile(np.arange(0, series_len, 1), n_series)
heatmap, xlabels, ylabels = np.histogram2d(x, y, bins=bins)
heatmap = skimage.transform.resize(heatmap, output_shape = (bins+1, bins+1), mode = "symmetric")
plt.contourf(xlabels, ylabels, heatmap.T)
plt.xlim(0, 1000)
plt.ylim(-0.5, 0.5)
plt.show()
Я не уверен, если это то, что вы хотите, но, может быть, попробовать
bins=200
?