Мотивация:
Я пытаюсь визуализировать набор данных из многих n-мерных векторов (скажем, у меня есть 10k векторов с n = 300 измерениями). То, что я хотел бы сделать, это рассчитать гистограмму для каждого из n измерений и построить ее в виде одной линии в бинарной карте * n.
Пока у меня есть это:
import numpy as np
import matplotlib
from matplotlib import pyplot as plt
%matplotlib inline
import seaborn as sns
# sample data:
vectors = np.random.randn(10000, 300) + np.random.randn(300)
def ndhist(vectors, bins=500):
limits = (vectors.min(), vectors.max())
hists = []
dims = vectors.shape[1]
for dim in range(dims):
h, bins = np.histogram(vectors[:, dim], bins=bins, range=limits)
hists.append(h)
hists = np.array(hists)
fig = plt.figure(figsize=(16, 9))
sns.heatmap(hists)
axes = fig.gca()
axes.set(ylabel='dimensions', xlabel='values')
print(dims)
print(limits)
ndhist(vectors)
Создает следующий вывод:
300
(-6.538069472429366, 6.52159540162285)
Проблема / Вопрос:
Как мне поменять тики осей?
- для оси y я бы просто хотел изменить это значение на значение по умолчанию для matplotlib, чтобы оно выбирало такие хорошие тики, как
0, 50, 100, ..., 250
(бонусные баллы за 299
или 300
)
- для оси x я хотел бы преобразовать показанные индексы бинов в границы бина (слева), затем, как и выше, я бы хотел изменить это обратно на выбор по умолчанию для matplotlib некоторых "хороших" тиков, таких как
-5, -2.5, 0, 2.5, 5
(бонусные баллы также включают фактические лимиты -6.538, 6.522
)
Собственные попытки решения:
Я уже пробовал много вещей, подобных следующей:
def ndhist_axlabels(vectors, bins=500):
limits = (vectors.min(), vectors.max())
hists = []
dims = vectors.shape[1]
for dim in range(dims):
h, bins = np.histogram(vectors[:, dim], bins=bins, range=limits)
hists.append(h)
hists = np.array(hists)
fig = plt.figure(figsize=(16, 9))
sns.heatmap(hists, yticklabels=False, xticklabels=False)
axes = fig.gca()
axes.set(ylabel='dimensions', xlabel='values')
#plt.xticks(np.linspace(*limits, len(bins)), bins)
plt.xticks(range(len(bins)), bins)
axes.xaxis.set_major_locator(matplotlib.ticker.AutoLocator())
plt.yticks(range(dims+1), range(dims+1))
axes.yaxis.set_major_locator(matplotlib.ticker.AutoLocator())
print(dims)
print(limits)
ndhist_axlabels(vectors)
Как видите, метки осей довольно неправильны. Я предполагаю, что экстент или пределы сохраняются где-то в исходной оси, но теряются при переключении обратно на AutoLocator
. Буду очень признателен за толчок в правильном направлении.