重绘后Matplotlib 3D散射颜色丢失

Dav*_*ker 14 python matplotlib

此问题相关,我想要一个每个点都有规定颜色的3D散点图.问题中发布的示例适用于我的系统,但在第一次重绘后(例如保存后或旋转图像时)颜色似乎丢失,即所有点都以蓝色绘制,并带有通常的深度信息.请参阅下面的修改示例.

我的系统是Python 2.6.7,在mac 10.8.0上从macports安装了matplotlib 1.1.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')
Run Code Online (Sandbox Code Playgroud)

这是两个图像,我得到: 第一张图片 第二张图片

Yan*_*ann 11

目前尚不清楚为什么会这样,而且肯定是一个错误.在这里,我提供了一个黑客来获得你想要的结果,虽然它不像你想要的那样自动化.

出于某种原因,Patch3DCollection在第一次渲染之后不会更新表示散点的情况.此更新至关重要,因为它是为每个集合修补程序设置唯一颜色的位置.要强制它重新初始化,您可以changedPatch3DCollection(实际上是一个ScalarMappable方法)上使用该方法,这只是记录发生了更改.绘制图形时,它会检查是否发生了更新,然后重新定义了颜色.如果没有,则跳过此过程.

要强制此更新自动发生,可以在每个'draw'事件上执行此操作.要做到这一点,就必须注册的方法使用canvasmpl_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')
Run Code Online (Sandbox Code Playgroud)

理想情况下,不应该要求这样做,并且scatCollection应该使用其他方法访问全局(我正在努力这样做).但这现在有用......