2012-01-23 36 views
13

Liên quan đến this question, tôi muốn có một ô phân tán 3D với các màu được quy định cho mỗi điểm. Ví dụ được đăng trong câu hỏi hoạt động trên hệ thống của tôi, nhưng sau lần vẽ đầu tiên (ví dụ sau khi lưu hoặc nếu tôi xoay hình ảnh), màu dường như bị mất, tức là tất cả các điểm được vẽ bằng màu xanh với thông tin chiều sâu thông thường. Vui lòng xem ví dụ đã sửa đổi bên dưới.Màu sắc phân tán 3D của Matplotlib bị mất sau khi vẽ lại

Hệ thống của tôi là Python 2.6.7 với matplotlib 1.1.0 được cài đặt từ macports trên máy Mac 10.8.0. Tôi sử dụng phần mềm phụ trợ MacOSX.

Có ai biết cách phá vỡ vấn đề này không?

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') 

Dưới đây là hai hình ảnh, tôi nhận được: First image Second image

+0

Hm, giống nhau trên cửa sổ. Nếu tôi nhận xét dòng 'col = np.arange (30) ', cả hai ô đều giống hệt nhau. Không thể giải thích lý do tại sao. 'pyplot' là một mô-đun stateful, và tôi không nghĩ rằng nó là khôn ngoan để mở một hình mới mà không đóng cái cũ. Nếu chỉ giữ một hình mở ra mọi lúc, tôi nghĩ rằng các hiệu ứng như vậy có thể được ngăn chặn. –

+0

Tôi chỉ nhận thấy rằng mã thực sự sử dụng hai số liệu. Tuy nhiên, đây không phải là nguyên nhân của vấn đề. Tôi đã xóa hình đầu tiên khỏi mã ví dụ và sự cố vẫn tiếp diễn. Cảm ơn bạn đã chỉ ra rằng sự cố cũng tồn tại trên cửa sổ. Dường như với tôi rằng đây là một loại lỗi. –

+0

Cũng giống như một lưu ý cho khách truy cập trong tương lai, điều này dường như được sửa trong MatPlotLib 1.2.0 :) – Poik

Trả lời

11

Đó là chưa rõ lý do tại sao điều này xảy ra, và nó chắc chắn là một lỗi. Ở đây tôi cung cấp một hack để có được kết quả mà bạn muốn, mặc dù nó không phải là tự động như một người muốn.

Vì lý do nào đó, Patch3DCollection đại diện cho các điểm phân tán không được cập nhật sau lần hiển thị đầu tiên. Bản cập nhật này là rất cần thiết vì đó là nơi các màu duy nhất được đặt cho từng bản vá bộ sưu tập. Để buộc nó khởi động lại, bạn có thể sử dụng phương pháp changed trên Patch3DCollection (thực sự là phương pháp ScalarMappable) và điều này chỉ là tài liệu thay đổi happend. Khi con số được vẽ, nó sẽ kiểm tra nếu một cập nhật xảy ra, và sau đó nó xác định lại màu sắc. Nếu không, quá trình này sẽ bị bỏ qua.

Để bắt buộc quá trình cập nhật này diễn ra tự động, người ta muốn thực hiện việc này trên mọi sự kiện 'vẽ'. Để thực hiện việc này, một người phải register a method sử dụng phương pháp mpl_connect của (xem hướng dẫn được liên kết).

Ví dụ này cho thấy cách lưu hình hai lần duy trì ánh xạ màu, nhưng nếu bạn bỏ ghi chú dòng plt.show(), nó sẽ vẫn hoạt động (ví dụ xoay vòng).

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') 

Lý tưởng nhất là nó không nên được yêu cầu để làm điều này, và toàn cầu scatCollection nên được truy cập sử dụng các phương pháp khác (tôi đang làm việc trên làm điều này). Nhưng điều này hoạt động ngay bây giờ ...

Các vấn đề liên quan