2016-08-30 2 views
0

Derzeit versuche ich, meinen eigenen benutzerdefinierten Legendenhandler zu erstellen, indem ich einen Proxy-Künstler (?) Patch mit PatchCollections erstellen und dann http://matplotlib.org/users/legend_guide.html folgen, um einen benutzerdefinierten Handler zu erstellen.Matplotlib PatchCollection zur Legende

Allerdings renne ich in eine Straßensperre in dem Versuch, dies in die Legende zu implementieren. Die Argumente für die Legende enthalten Patches, aber keine Patch-Sammlungen.

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.mlab as mlab 
import matplotlib.patches as mpatches 
from matplotlib.path import Path 
from matplotlib.collections import PatchCollection 

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

verts1 = [(0.,0.),(0.,1.),(1.,1.),(0.51,0.51),(0.,0.),(0.,0.),] 
codes1 = [Path.MOVETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.MOVETO,Path.CLOSEPOLY,] 
path1 = Path(verts1,codes1) 
patch1 = mpatches.PathPatch(path1,ls='dashed',ec='red',facecolor="none") 


verts2 = [(0.49,0.49),(0.,0.),(1.,0.),(1.,1.),(0.5,0.5),(0.,0.),] 
codes2 = [Path.MOVETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.MOVETO,Path.CLOSEPOLY,] 
path2 = Path(verts2,codes2) 
patch2 = mpatches.PathPatch(path2,ls='solid',edgecolor='red', facecolor="none") 

patch = PatchCollection([patch1,patch2],match_original=True) 

ax.set_xlim(-2,2) 
ax.set_ylim(-2,2) 

ax.add_collection(patch) 

Visual

Obiges ist der Code des Handlers zu visualisieren. Im Wesentlichen ein Rechteck mit dem oberen Dreieck als gestrichelte Linien und den unteren als Fest

Unter Verwendung

plt.legend([patch],["hellocello"],loc='upper right') 

erstellt den Fehler. Gibt es eine Problemumgehung?

Antwort

2

Aus dem Beispiel in diesem section, sieht es aus wie Sie ein Objekt definieren müssen und alle Koordinaten in Bezug auf die handlebox Größe ausdrücken,

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.mlab as mlab 
import matplotlib.patches as mpatches 
from matplotlib.path import Path 
from matplotlib.collections import PatchCollection 

class AnyObject(object): 
    pass 

class AnyObjectHandler(object): 
    def legend_artist(self, legend, orig_handle, fontsize, handlebox): 
     x0, y0 = handlebox.xdescent, handlebox.ydescent 
     width, height = handlebox.width, handlebox.height 
     hw = 0.5*width; hh = 0.5*height 
     verts1 = [(x0,y0),(x0,y0+height),(x0+width,y0+height),((x0+hw)*1.01,(y0+hh)*1.01),(x0,y0),(x0,y0),] 
     codes1 = [Path.MOVETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.MOVETO,Path.CLOSEPOLY,] 
     path1 = Path(verts1,codes1) 
     patch1 = mpatches.PathPatch(path1,ls='dashed',ec='red',facecolor="none") 

     verts2 = [((x0+hw)*0.99,(y0+hh)*0.99),(x0,y0),(x0+width,y0),(x0+width,y0+height),(x0+hw,y0+hh),(x0,y0),] 
     codes2 = [Path.MOVETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.MOVETO,Path.CLOSEPOLY,] 
     path2 = Path(verts2,codes2) 
     patch2 = mpatches.PathPatch(path2,ls='solid',edgecolor='red', facecolor="none") 

     patch = PatchCollection([patch1,patch2],match_original=True) 

     handlebox.add_artist(patch) 
     return patch 


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

ax.set_xlim(-2,2) 
ax.set_ylim(-2,2) 

plt.legend([AnyObject()], ['hellocello'], 
      handler_map={AnyObject: AnyObjectHandler()}) 

plt.show() 

Dies scheint für mich mit PatchCollection, zumindest in Ordnung zu arbeiten auf matplotlib Version 1.4.3. Das Ergebnis sieht so aus,

enter image description here

+0

Hallo, Ihre letzte Aussage war SpotOn. Meine Version von Matplotlib 1.3.1 hatte Probleme und als ich auf 1.5.x (?) Upgraden konnte, war es gelöst. Vielen Dank! –

+0

Großartig, dass es jetzt funktioniert - im Zweifelsfall die Software aktualisieren :) –