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

Matplotlib 3D-цвет рассеяния, потерянный после перерисовки

В связи с этот вопрос, я хочу трехмерный график рассеяния с заданными цветами для каждой точки. Пример, опубликованный в вопросе, работает в моей системе, но после первого перерисовки (например, после сохранения или если я поворачиваю изображение) цвет кажется потерянным, т.е. Все точки рисуются синим цветом с обычной информацией о глубине. См. Приведенный ниже пример.

Моя система - это Python 2.6.7, где matplotlib 1.1.0 установлен из macports на mac 10.8.0. Я использую сервер MacOSX.

Кто-нибудь знает, как обойти эту проблему?

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

# Create Map
cm = plt.get_cmap("RdYlGn")

x = np.random.rand(30)
y = np.random.rand(30)
z = np.random.rand(30)

col = np.arange(30)

fig = plt.figure()
ax3D = fig.add_subplot(111, projection='3d')
ax3D.scatter(x, y, z, s=30, c=col, marker='o', cmap=cm)

plt.savefig('image1.png')
plt.savefig('image2.png')

Вот два изображения, я получаю: First imageSecond image

4b9b3361

Ответ 1

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

По какой-то причине Patch3DCollection, представляющий точки разброса, не обновляется после первого рендеринга. Это обновление имеет важное значение, поскольку именно для каждого патча коллекции установлены уникальные цвета. Чтобы заставить его повторить инициализацию, вы можете использовать метод changed в методе Patch3DCollection (действительно a ScalarMappable), и это просто документы о том, что произошло изменение. Когда рисунок рисуется, он проверяет, произошло ли обновление, а затем переопределяет цвета. Если это не так, этот процесс пропускается.

Чтобы заставить это обновление происходить автоматически, хотелось бы сделать это на каждом событии 'draw'. Для этого нужно зарегистрировать метод с помощью метода canvas mpl_connect (см. Связанный учебник).

В этом примере показано, как сохранение цифры дважды сохраняет цветовое сопоставление, но если вы раскомментируете строку plt.show(), она все равно будет работать (например, при вращении).

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

# Create Map
cm = plt.get_cmap("RdYlGn")

# added a seed so consistant plotting of points
np.random.seed(101)
x = np.random.rand(30)
y = np.random.rand(30)
z = np.random.rand(30)

col = np.arange(30)

fig = plt.figure()
#ax = fig.add_subplot(111)
#scatCollection = ax.scatter(x,y,
ax3D = fig.add_subplot(111, projection='3d')
# keep track of the Patch3DCollection:
scatCollection = ax3D.scatter(x, y, z, s=30, 
                            c=col, 
                            marker='o',
                            cmap=cm
                            )
def forceUpdate(event):
    global scatCollection
    scatCollection.changed()

fig.canvas.mpl_connect('draw_event',forceUpdate)

#plt.show()

plt.savefig('image1.png')

plt.savefig('image2.png')

В идеале этого не требуется, и глобальный scatCollection должен быть доступен с помощью других методов (я работаю над этим). Но это работает сейчас...