2012-01-23 34 views
13

this question से संबंधित, मैं प्रत्येक बिंदु के लिए निर्धारित रंगों के साथ एक 3 डी स्कैटर प्लॉट चाहता हूं। प्रश्न में पोस्ट किया गया उदाहरण मेरे सिस्टम पर काम करता है, लेकिन पहले रेड्रा के बाद (उदाहरण के लिए सहेजने के बाद या अगर मैं छवि घुमाता हूं) रंग खो जाता प्रतीत होता है, यानी सभी बिंदुओं को सामान्य गहराई से जानकारी के साथ नीले रंग में खींचा जाता है। कृपया नीचे संशोधित उदाहरण देखें।Matplotlib 3 डी स्कैटर रंग redraw

मेरा सिस्टम पाइथन 2.6.7 है मैकप्लॉटिब 1.1.0 मैक 10.8.0 पर मैकपोर्ट से स्थापित है। मैं मैकॉक्स बैकएंड का उपयोग करता हूं।

क्या कोई इस समस्या को बाधित करने के बारे में जानता है?

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 image Second image

+0

एचएम, विंडोज़ पर ही। अगर मैं लाइन 'col = np.arange (30) ' पर टिप्पणी करता हूं, तो दोनों भूखंड समान आते हैं। क्यों समझा नहीं जा सकता है। 'pyplot' एक राज्यव्यापी मॉड्यूल है, और मुझे नहीं लगता कि पुराने को बंद किए बिना एक नया आंकड़ा खोलना बुद्धिमान है। यदि हर समय केवल एक ही आंकड़ा खुला रहता है, तो मुझे लगता है कि ऐसे प्रभावों को रोका जा सकता है। –

+0

मैंने अभी देखा है कि कोड वास्तव में दो आंकड़ों का उपयोग करता है। हालांकि, समस्या का कारण यह नहीं था। मैंने उदाहरण कोड से पहला आंकड़ा हटा दिया और समस्या बनी हुई है। यह इंगित करने के लिए धन्यवाद कि विंडोज़ पर समस्या भी मौजूद है। ऐसा लगता है कि यह किसी तरह की बग है। –

+0

भविष्य के आगंतुकों के लिए एक नोट के रूप में, यह MatPlotLib 1.2.0 में तय किया गया प्रतीत होता है :) – Poik

उत्तर

11

यह क्यों यह हो रहा है स्पष्ट नहीं है, और यह निश्चित रूप से एक बग है। यहां मैं परिणाम प्राप्त करने के लिए एक हैक प्रदान करता हूं, हालांकि यह स्वचालित रूप से एक जैसा नहीं चाहता है।

किसी कारण से, Patch3DCollection स्कैटर बिंदुओं का प्रतिनिधित्व करने वाले पहले प्रतिपादन के बाद अद्यतन नहीं किया गया है। यह अद्यतन आवश्यक है, क्योंकि यह वह जगह है जहां प्रत्येक संग्रह पैच के लिए अद्वितीय रंग सेट किए जाते हैं। इसे पुन: प्रारंभ करने के लिए मजबूर करने के लिए, आप विधि Patch3DCollection (वास्तव में ScalarMappable विधि) पर उपयोग कर सकते हैं, और यह केवल दस्तावेज है कि खुशी में परिवर्तन करें। जब आंकड़ा खींचा जाता है, तो यह जांचता है कि कोई अपडेट हुआ है, और फिर यह रंगों को फिर से परिभाषित करता है। यदि ऐसा नहीं होता है, तो यह प्रक्रिया छोड़ दी जाती है।

इस अद्यतन को स्वचालित रूप से होने के लिए मजबूर करने के लिए, कोई भी प्रत्येक 'ड्रा' ईवेंट पर ऐसा करना चाहता है। ऐसा करने के लिए, canvas की mpl_connect विधि (लिंक किए गए ट्यूटोरियल देखें) का उपयोग करके register a method अवश्य होना चाहिए।

यह उदाहरण दिखाता है कि आकृति को दो बार रंग मैपिंग को कैसे संरक्षित करता है, लेकिन यदि आप 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 अन्य विधियों (मैं यह कर रहा पर काम कर रहा हूँ) का उपयोग करके एक्सेस किया जाना चाहिए। लेकिन यह अब के लिए काम करता है ...

संबंधित मुद्दे