Подтвердить что ты не робот

Построение 3d-рассеяния в matplotlib

У меня есть набор матриц Nx3 в scipy/numpy, и я хотел бы сделать его трехмерный разброс, где оси X и Y определяются значениями первого и второго столбцов матрицы, высота каждого бара является третьим столбцом в матрице, а число баров определяется N.

Каждая матрица представляет собой другую группу данных, и я хочу, чтобы каждая была построена с другим цветом, а затем задала легенду для всего рисунка.

У меня есть следующий код:

fig = pylab.figure()
s = plt.subplot(1, 1, 1)
colors = ['k', "#B3C95A", 'b', '#63B8FF', 'g', "#FF3300",
          'r', 'k']
ax = Axes3D(fig)
plots = []
index = 0

for data, curr_color in zip(datasets, colors):
    p = ax.scatter(log2(data[:, 0]), log2(data[:, 1]),
                   log2(data[:, 2]), c=curr_color, label=my_labels[index])

    s.legend()
    index += 1

    plots.append(p)

    ax.set_zlim3d([-1, 9])
    ax.set_ylim3d([-1, 9])
    ax.set_xlim3d([-1, 9])

Проблема в том, что ax.scatter отображает вещи с прозрачностью, и я бы хотел, чтобы это удалялось. Кроме того, я хотел бы установить xticks и yticks и zticks - как я могу это сделать?

Наконец, вызов легенды не появляется, хотя я вызываю label = "" для каждого разворот вызова. Как я могу получить легенду?

Большое спасибо за вашу помощь.

4b9b3361

Ответ 1

Попробуйте заменить "ax.scatter" на ax.plot ', возможно, с параметром' o ', чтобы получить похожие круги. Это фиксирует прозрачность и легенду.

import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
from numpy.random import random

mpl.rcParams['legend.fontsize'] = 10

fig = plt.figure(1)
fig.clf()
ax = Axes3D(fig)
datasets = random((8,100,3))*512
my_labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

colors = ['k', "#B3C95A", 'b', '#63B8FF', 'g', "#FF3300",
          'r', 'k']
index = 0
for data, curr_color in zip(datasets, colors):
    ax.plot(np.log2(data[:, 0]), np.log2(data[:, 1]), 
                   np.log2(data[:, 2]), 'o', c=curr_color, label=my_labels[index])
    index += 1

ax.set_zlim3d([-1, 9])
ax.set_ylim3d([-1, 9])
ax.set_xlim3d([-1, 9])

ax.set_xticks(range(0,11))
ax.set_yticks([1,2,8])
ax.set_zticks(np.arange(0,9,.5))

ax.legend(loc = 'upper left')

plt.draw()

plt.show()

Я добавил несколько строк и настроек, чтобы получить некоторые примеры данных и получить остальную часть вашей демоверсии. Я предполагаю, что вы сможете заставить его работать.

Настройка тиков требует обновления августа 2010 года mplot3d, как описано здесь. Я получил последний mplot3d из Sourceforge. Я не совсем уверен, что Matplotlib 1.0.1 содержит это последнее обновление, поскольку я все еще запускаю Python 2.6 с Matplotlib 1.0.0.

Изменить

Быстрый и грязный фиктивный сюжет для легенд, сохраняя эффект прозрачности 3D, который вы получаете от разброса:

index = 0
for data, curr_color in zip(datasets, colors):
    ax.scatter(np.log2(data[:, 0]), np.log2(data[:, 1]), 
                   np.log2(data[:, 2]), 'o', c=curr_color, label=my_labels[index])
    ax.plot([], [], 'o', c = curr_color, label=my_labels[index])                    
    index += 1

Ответ 2

AFAIK, легенды для художников 3D-разброса напрямую не поддерживаются. Глянь сюда: http://matplotlib.sourceforge.net/users/legend_guide.html#plotting-guide-legend

Однако вы можете использовать hack/work-around с "прокси-исполнителем", используя что-то вроде:

p = Rectangle((0, 0), 1, 1, fc="r")
axis.legend([p], ["Red Rectangle"])

Таким образом, прокси-художник не будет добавлен к оси, но вы можете использовать его для создания легенды.

Ответ 3

Настройка знака глубины kwarg = False исправил это для меня:

ax.scatter(np.log2(data[:, 0]), np.log2(data[:, 1]), 
               np.log2(data[:, 2]), 'o', c=curr_color,  label=my_labels[index], depthshade=False)