2016-08-30 3 views
0

В настоящее время я пытаюсь создать собственный обработчик легенды, создав патч-прокси (?) С помощью PatchCollections, а затем следуя http://matplotlib.org/users/legend_guide.html, чтобы создать пользовательский обработчик.Matplotlib PatchCollection to Legend

Однако я бегу в блокпост, пытаясь реализовать это в легенде. Аргументы для легенды берут патчи, но не patchcollections.

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

Выше приведен код для визуализации обработчика. В основном прямоугольник с верхним треугольником в виде пунктирных линий и нижним в виде твердого

Использования,

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

Воссоздается ошибка. Есть ли обходной путь?

ответ

2

Из примера в этой section, похоже, вам нужно определить объект и выразить все координаты точки зрения размера handlebox,

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

Это, кажется, работает хорошо с PatchCollection, по крайней мере для меня на matplotlib версия 1.4.3. Результат выглядит,

enter image description here

+0

Привет, ваше последнее утверждение было SpotOn. Моя версия matplotlib 1.3.1 имела проблемы, и когда я обновился до 1.5.x (?), Она была решена. Большое спасибо! –

+0

Отлично, что сейчас работает - если есть сомнения, обновите программное обеспечение :) –

Смежные вопросы