2012-07-20 21 views
7

इसी तरह से previous question मेरा, मैं matplotlib का उपयोग करके खींची जा रही रेखाओं की टोपी को नियंत्रित करना चाहता हूं। हालांकि, मेरे पास लाइनों की एक बड़ी संख्या है, और लाइन संग्रह के अलावा किसी अन्य चीज़ के साथ ड्राइंग बहुत लंबा रास्ता लेता है। एक सामान्य तरीके से रेखा संग्रह में लाइनों के केश को नियंत्रित करने के लिए कोई कामकाज है (या वैकल्पिक रूप से, बड़ी संख्या में Line2D लाइनों को चित्रित करने के सुपर फास्ट तरीके)। उदाहरण के लिए, मैंने matplotlib आरसी सेटिंग्स का उपयोग करके कोशिश की है:matplotlib - रेखा संग्रह/लाइनों की बड़ी संख्या का नियंत्रण कैप्स्टाइल

import matplotlib as mpl 
mpl.rcParams['lines.solid_capstyle'] = 'round' 
mpl.rcParams['lines.solid_joinstyle'] = 'round' 

लेकिन ऐसा कोई प्रभाव नहीं दिखता है। collections.py के लिए docstring से:

कक्षाएं उनके एक तत्व समकक्षों के रूप में के रूप में लचीला होना करने के लिए नहीं कर रहे हैं (उदाहरण के लिए आप सभी लाइन शैलियों का चयन करने में सक्षम नहीं हो सकता है), लेकिन वे आम उपयोग स्थितियों में तेजी से हो के लिए होती हैं (उदाहरण के लिए ठोस लाइन के एक बड़े सेट segemnts)

बताते हैं कौन सा क्यों मैं विभिन्न मापदंडों पर नियंत्रण नहीं कर पा रहे, लेकिन मैं अभी भी यह करने के लिए चाहते हैं! मैंने एजीजी बैकएंड के लिए कोड देखा है (_backend_agg.cpp: नहीं कि मैं इसे वास्तव में समझता हूं), और ऐसा लगता है कि line_cap और line_join gc.cap और gc.join द्वारा नियंत्रित होते हैं, जहां जीसी GCAgg कक्षा से आता है। क्या किसी को पता है कि कोई इसे पायथन से कैसे नियंत्रित कर सकता है? क्या मैं यहां सही सवाल पूछ रहा हूं? शायद इन मानकों को नियंत्रित करने के आसान तरीके हैं?

किसी भी मदद की बहुत सराहना की जाती है ... मैं इस काम को पाने के लिए बेताब हूं, इसलिए पागल हैक्स का भी स्वागत है!

धन्यवाद,

कार्सन

उत्तर

3

चूंकि आप अपने प्रश्न में उल्लेख करते हैं कि आपको "गंदे" समाधान नहीं हैं, एक विकल्प निम्नानुसार होगा।

एक विशेष LineCollection की "ड्राइंग प्रक्रिया" draw विधि Collection वर्ग (LineCollection के आधार) में परिभाषित द्वारा नियंत्रित किया जाता। यह विधि gc = renderer.new_gc() कथन के माध्यम से GraphicsContextBase (backend_bases.py में परिभाषित) का एक उदाहरण बनाता है। ऐसा लगता है कि यह वस्तु वास्तव में capstyle (संपत्ति _capstyle) को नियंत्रित करने वाली अन्य चीज़ों के बीच शासित है। इसलिए, एक GraphicsContextBase उपवर्ग सकता है, _capstyle संपत्ति को ओवरराइड, और RendererBase वर्ग में एक नई new_gc विधि इंजेक्षन ताकि new_gc वापसी के फलस्वरूप कॉल अनुकूलित उदाहरण:

@florisvb द्वारा जवाब से उदाहरण उधार (python3 कल्पना करते हुए) :

#!/usr/bin/env python 
import types 

import numpy as np 
from matplotlib.backend_bases import GraphicsContextBase, RendererBase 
import matplotlib.pyplot as plt 
from matplotlib.collections import LineCollection 

class GC(GraphicsContextBase): 
    def __init__(self): 
     super().__init__() 
     self._capstyle = 'round' 

def custom_new_gc(self): 
    return GC() 

RendererBase.new_gc = types.MethodType(custom_new_gc, RendererBase) 
#---------------------------------------------------------------------- 
np.random.seed(42) 

x = np.random.random(10) 
y = np.random.random(10) 

points = np.array([x, y]).T.reshape((-1, 1, 2)) 
segments = np.concatenate([points[:-1], points[1:]], axis=1) 

fig = plt.figure() 
ax = fig.add_subplot(111) 

linewidth = 10 
lc = LineCollection(segments, linewidths=linewidth) 
ax.add_collection(lc) 

fig.savefig('fig.png') 

यह पैदा करता है: enter image description here

+0

अच्छा लगा। वह बहुत खूबसूरत लग रहा है! धन्यवाद @ewcz! –

+0

@ewcz यह समाधान एजीजी आधारित आउटपुट के लिए बहुत अच्छा काम करता है, धन्यवाद!मैं अन्य बैकएंड्स के लिए स्रोत देख रहा हूं क्योंकि मैं इस प्रभाव को पीडीएफ में भी प्राप्त करना चाहता हूं। मुझे 'पीएस' या 'पीडीएफ' बैकएंड्स को आपके द्वारा लिखे गए पैच को स्वीकार करने के लिए प्रतीत नहीं होता है, लेकिन दिलचस्प रूप से 'svg' बैकएंड इसे संभाल सकता है। पीडीएफ आउटपुट के लिए इस पैच को ट्विक करने के बारे में कोई विचार? – aorr

1

मैं एक ही मुद्दे के साथ संघर्ष कर रहा था। मैंने अपने लाइन संग्रह के शीर्ष पर एक स्कैटर प्लॉट की योजना बनाई। यह सही नहीं है, लेकिन यह आपके आवेदन के लिए काम कर सकता है। कुछ subtleties है - नीचे एक कामकाजी उदाहरण है।

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.collections import LineCollection 

x = np.random.random(10) 
y = np.random.random(10) 
z = np.arange(0,10) 

points = np.array([x, y]).T.reshape(-1, 1, 2) 
segments = np.concatenate([points[:-1], points[1:]], axis=1) 

fig = plt.figure() 
ax = fig.add_subplot(111) 

linewidth = 10 
cmap = plt.get_cmap('jet') 
norm = plt.Normalize(np.min(z), np.max(z)) 
color = cmap(norm(z)) 

lc = LineCollection(segments, linewidths=linewidth, cmap=cmap, norm=norm) 
lc.set_array(z) 
lc.set_zorder(z.tolist()) 
ax.add_collection(lc) 

ax.scatter(x,y,color=color,s=linewidth**2,edgecolor='none', zorder=(z+2).tolist()) 
संबंधित मुद्दे