Я пытаюсь создать фигуру, в которой каждое измерение многомерного набора данных нанесено на график по каждому другому в сетке подзаголовков. Вот то, что я до сих пор:«Фальшивая» ось тиков и меток с Matplotlib
Х размер определяется по столбцу подзаговор и размерность у определяется ряд. Когда размеры равны, накладывается 1-гистограмма с плотностью по оси y, в противном случае используется 2d гистограмма с плотностью, отображаемой на цвет. При создании каждого подзаголовка я разделяю ось x с первым графиком в этом столбце (используя аргумент sharex
в функции Figure.add_subplot
). Оси Y разделяются аналогично, за исключением 1d гистограмм.
Это хорошо работает, чтобы держать оси в одном масштабе, но вы можете увидеть проблему в левом верхнем углу. Поскольку большинство осей одинаковы для строк и столбцов, у меня есть только метки в нижней и левой частях фигуры. Проблема в том, что верхняя левая подзадача имеет другую шкалу y, чем остальная часть ее строки.
Я хочу на самом деле иметь тики для осей y других подзаговоров в строке, применяемых к верхнему левому подзаголовку, без, изменяя пределы y подзаголовка. Получение y меток из второго подзаголовка в строке и установка их на первые работы, но фактическое изменение положения тиков не происходит, поскольку пределы осей не совпадают. Я не могу решить, как установить позиции тика в относительных терминах, кроме явного преобразования точек из шкалы одного графика в другой.
EDIT: Так как кто-то спросил, вот базовая версия кода используется для генерации этого:
import numpy as np
from scipy.stats import gaussian_kde
def matrix_plot(figure, data, limits, labels):
"""
Args:
figure: matplotlib Figure
data: numpy.ndarray, points/observations in rows
limits: list of (min, max) values for axis limits
labels: list of labels for each dimension
"""
# Number of dimensions (data columns)
ndim = data.shape[1]
# Create KDE objects
density = [ gaussian_kde(data[:,dim]) for dim in range(ndim) ]
# Keep track of subplots
plots = np.ndarray((ndim, ndim), dtype=object)
# Loop through dimensions twice
# dim1 goes by column
for dim1 in range(ndim):
# dim2 goes by row
for dim2 in range(ndim):
# Index of plot
i = dim2 * ndim + dim1 + 1
# Share x-axis with plot at top of column
# Share y-axis with plot at beginning of row, unless that
# plot or current plot is a 1d plot
kwargs = dict()
if dim2 > 0:
kwargs['sharex'] = plots[0][dim1]
if dim1 > 0 and dim1 != dim2:
kwargs['sharey'] = plots[dim2][0]
elif dim1 > 1:
kwargs['sharey'] = plots[dim2][1]
# Create new subplot
# Pass in shared axis arguments with **kwargs
plot = figure.add_subplot(ndim, ndim, i, **kwargs)
plots[dim2][dim1] = plot
# 1d density plot
if dim1 == dim2:
# Space to plot over
x = np.linspace(limits[dim][0], limits[dim][1], 100)
# Plot filled region
plot.set_xlim(limits[dim])
plot.fill_between(x, density[dim].evaluate(x))
# 2d density plot
else:
# Make histogram
h, xedges, yedges = np.histogram2d(data[:,dim1],
data[:,dim2], range=[limits[dim1], limits[dim2]],
bins=250)
# Set zero bins to NaN to make empty regions of
# plot transparent
h[h == 0] = np.nan
# Plot without grid
plot.imshow(h.T, origin='lower',
extent=np.concatenate((limits[dim1], limits[dim2])),
aspect='auto')
plot.grid(False)
# Ticks and labels of except on figure edges
plot.tick_params(axis='both', which='both', left='off',
right='off', bottom='off', top='off', labelleft='off',
labelbottom='off')
if dim1 == 0:
plot.tick_params(axis='y', left='on', labelleft='on')
plot.set_ylabel(labels[dim2])
if dim2 == self._ndim - 1:
plot.tick_params(axis='x', bottom='on', labelbottom='on')
plot.set_xlabel(labels[dim1])
# Tight layout
figure.tight_layout(pad=.1, h_pad=0, w_pad=0)
А вот то, что я получаю, когда я пытаюсь скопировать тик позиции и этикетки от у-оси второй участок в первом ряду на первый участок:
plots[0][0].set_yticks(plots[0][1].get_yticks())
plots[0][0].set_yticklabels(plots[0][1].get_yticklabels())
Обратите внимание, как он присваивает клещ позицию по абсолютной шкале, которая значительно выше, тх n масштаб графика плотности. Пределы оси расширяются, чтобы показать тики, поэтому фактическая кривая плотности раздавливается вниз. Кроме того, ярлыки не отображаются.
Возможно, вы можете подделать его с помощью [set_yticklabels] (http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.set_yticklabels) и set_yticks –
Какой код вы использовали для создания? Это поможет понять, как вы это сделали. Кроме того, на самом деле не ответ на ваш вопрос, но вы можете попробовать использовать 'scatter_matrix' из [pandas] (http://pandas.pydata.org/pandas-docs/stable/visualization.html # plotting-tools) - он делает этот точный вид сюжета и должен правильно обрабатывать эти пределы. – Ajean
Я отредактировал вопрос с примером кода и результатами с копированием тиков с графика 2 гистограммы на верхний график плотности. – JaredL