Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0c3410e

Browse files
committed
Applied scatleg patch
svn path=/trunk/matplotlib/; revision=6280
1 parent 0a9f746 commit 0c3410e

3 files changed

Lines changed: 70 additions & 13 deletions

File tree

CHANGELOG

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
2008-10-20 Applied scatleg patch based on ideas and work by Erik
2+
Tollerud and Jae-Joon Lee. - MM
3+
14
2008-10-11 Fixed bug in pdf backend: if you pass a file object for
25
output instead of a filename, e.g. in a wep app, we now
36
flush the object at the end. - JKS

lib/matplotlib/collections.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,12 @@ def get_datalim(self, transData):
148148
result = result.inverse_transformed(transData)
149149
return result
150150

151+
def get_window_extent(self, renderer):
152+
bbox = self.get_datalim(transforms.IdentityTransform())
153+
#TODO:check to ensure that this does not fail for
154+
#cases other than scatter plot legend
155+
return bbox
156+
151157
def _prepare_points(self):
152158
"""Point prep for drawing and hit testing"""
153159

@@ -417,6 +423,18 @@ def update_scalarmappable(self):
417423
else:
418424
self._edgecolors = self.to_rgba(self._A, self._alpha)
419425

426+
def update_from(self, other):
427+
'copy properties from other to self'
428+
429+
artist.Artist.update_from(self, other)
430+
self._antialiaseds = other._antialiaseds
431+
self._edgecolors_original = other._edgecolors_original
432+
self._edgecolors = other._edgecolors
433+
self._facecolors_original = other._facecolors_original
434+
self._facecolors = other._facecolors
435+
self._linewidths = other._linewidths
436+
self._linestyles = other._linestyles
437+
self._pickradius = other._pickradius
420438

421439
# these are not available for the object inspector until after the
422440
# class is built so we define an initial set here for the init
@@ -690,6 +708,7 @@ def __init__(self,
690708
"""
691709
Collection.__init__(self,**kwargs)
692710
self._sizes = sizes
711+
self._numsides = numsides
693712
self._paths = [self._path_generator(numsides)]
694713
self._rotation = rotation
695714
self.set_transform(transforms.IdentityTransform())
@@ -706,6 +725,15 @@ def draw(self, renderer):
706725
def get_paths(self):
707726
return self._paths
708727

728+
def get_numsides(self):
729+
return self._numsides
730+
731+
def get_rotation(self):
732+
return self._rotation
733+
734+
def get_sizes(self):
735+
return self._sizes
736+
709737

710738
class StarPolygonCollection(RegularPolyCollection):
711739
"""

lib/matplotlib/legend.py

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ def __init__(self, parent, handles, labels,
9292
handlelen = None, # the length of the legend lines
9393
handletextsep = None, # the space between the legend line and legend text
9494
axespad = None, # the border between the axes and legend edge
95-
96-
shadow = None
95+
shadow = None,
96+
scatteryoffsets=None,
9797
):
9898
"""
9999
parent # the artist that contains the legend
@@ -105,6 +105,7 @@ def __init__(self, parent, handles, labels,
105105
pad = 0.2 # the fractional whitespace inside the legend border
106106
markerscale = 0.6 # the relative size of legend markers vs. original
107107
shadow # if True, draw a shadow behind legend
108+
scatteryoffsets # a list of yoffsets for scatter symbols in legend
108109
109110
The following dimensions are in axes coords
110111
labelsep = 0.005 # the vertical space between the legend entries
@@ -117,8 +118,10 @@ def __init__(self, parent, handles, labels,
117118

118119
Artist.__init__(self)
119120

120-
proplist=[numpoints, pad, borderpad, markerscale, labelsep, handlelen, handletextsep, axespad, shadow]
121-
propnames=['numpoints', 'pad', 'borderpad', 'markerscale', 'labelsep', 'handlelen', 'handletextsep', 'axespad', 'shadow']
121+
proplist=[numpoints, pad, borderpad, markerscale, labelsep,
122+
handlelen, handletextsep, axespad, shadow, scatteryoffsets]
123+
propnames=['numpoints', 'pad', 'borderpad', 'markerscale', 'labelsep',
124+
'handlelen', 'handletextsep', 'axespad', 'shadow', 'scatteryoffsets']
122125
for name, value in safezip(propnames,proplist):
123126
if value is None:
124127
value=rcParams["legend."+name]
@@ -134,6 +137,14 @@ def __init__(self, parent, handles, labels,
134137
self.prop=prop
135138
self.fontsize = self.prop.get_size_in_points()
136139

140+
# introduce y-offset for handles of the scatter plot
141+
if scatteryoffsets is None:
142+
self._scatteryoffsets = np.array([4./8., 5./8., 3./8.])
143+
else:
144+
self._scatteryoffsets = np.asarray(scatteryoffsets)
145+
reps = int(self.numpoints / len(self._scatteryoffsets)) + 1
146+
self._scatteryoffsets = np.tile(self._scatteryoffsets, reps)[:self.numpoints]
147+
137148
if isinstance(parent,Axes):
138149
self.isaxes = True
139150
self.set_figure(parent.figure)
@@ -306,15 +317,26 @@ def _get_handles(self, handles, texts):
306317
ret.append(legline)
307318

308319
elif isinstance(handle, RegularPolyCollection):
309-
if self.numpoints == 1:
310-
xdata = np.array([left])
311-
p = Rectangle(xy=(min(xdata), y-3/4*HEIGHT),
312-
width = self.handlelen, height=HEIGHT/2,
313-
)
314-
p.set_facecolor(handle._facecolors[0])
315-
if handle._edgecolors != 'none' and len(handle._edgecolors):
316-
p.set_edgecolor(handle._edgecolors[0])
317-
self._set_artist_props(p)
320+
# the ydata values set here have no effects as it will
321+
# be updated in the _update_positions() method.
322+
ydata = (y-HEIGHT/2)*np.ones(np.asarray(xdata_marker).shape, float)
323+
324+
size_max, size_min = max(handle.get_sizes()),\
325+
min(handle.get_sizes())
326+
# we may need to scale these sizes by "markerscale"
327+
# attribute. But other handle types does not seem
328+
# to care about this attribute and it is currently ignored.
329+
sizes = [.5*(size_max+size_min), size_max,
330+
size_min]
331+
332+
p = type(handle)(handle.get_numsides(),
333+
rotation=handle.get_rotation(),
334+
sizes=sizes,
335+
offsets=zip(xdata_marker,ydata),
336+
transOffset=self.get_transform())
337+
338+
p.update_from(handle)
339+
p.set_figure(self.figure)
318340
p.set_clip_box(None)
319341
p.set_clip_path(None)
320342
ret.append(p)
@@ -532,6 +554,10 @@ def get_tbounds(text): #get text bounds in axes coords
532554
elif isinstance(handle, Rectangle):
533555
handle.set_y(y+1/4*h)
534556
handle.set_height(h/2)
557+
elif isinstance(handle,RegularPolyCollection):
558+
offsets = handle.get_offsets()
559+
offsets[:,1] = y+h*self._scatteryoffsets
560+
handle.set_offsets(offsets)
535561

536562
# Set the data for the legend patch
537563
bbox = self._get_handle_text_bbox(renderer)

0 commit comments

Comments
 (0)