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

Skip to content

Commit 8d120db

Browse files
committed
Fix single pixel markers. The pixel shape is now optimized so it does the right thing in the Agg backend. For raster backends, linejoin and cap styles is now correctly passed to and used in the backend.
1 parent 59037fb commit 8d120db

File tree

5 files changed

+61
-15
lines changed

5 files changed

+61
-15
lines changed

lib/matplotlib/backends/backend_pdf.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,7 @@ def writeImages(self):
12131213

12141214
img.flipud_out()
12151215

1216-
def markerObject(self, path, trans, fillp, strokep, lw):
1216+
def markerObject(self, path, trans, fillp, strokep, lw, joinstyle, capstyle):
12171217
"""Return name of a marker XObject representing the given path."""
12181218
# self.markers used by markerObject, writeMarkers, close:
12191219
# mapping from (path operations, fill?, stroke?) to
@@ -1228,7 +1228,7 @@ def markerObject(self, path, trans, fillp, strokep, lw):
12281228
# first two components of each value in self.markers to be the
12291229
# name and object reference.
12301230
pathops = self.pathOperations(path, trans, simplify=False)
1231-
key = (tuple(pathops), bool(fillp), bool(strokep))
1231+
key = (tuple(pathops), bool(fillp), bool(strokep), joinstyle, capstyle)
12321232
result = self.markers.get(key)
12331233
if result is None:
12341234
name = Name('M%d' % len(self.markers))
@@ -1242,13 +1242,15 @@ def markerObject(self, path, trans, fillp, strokep, lw):
12421242
return name
12431243

12441244
def writeMarkers(self):
1245-
for ((pathops, fillp, strokep),
1245+
for ((pathops, fillp, strokep, joinstyle, capstyle),
12461246
(name, ob, bbox, lw)) in self.markers.iteritems():
12471247
bbox = bbox.padded(lw * 0.5)
12481248
self.beginStream(
12491249
ob.id, None,
12501250
{'Type': Name('XObject'), 'Subtype': Name('Form'),
12511251
'BBox': list(bbox.extents) })
1252+
self.output(GraphicsContextPdf.joinstyles[joinstyle], Op.setlinejoin)
1253+
self.output(GraphicsContextPdf.capstyles[capstyle], Op.setlinecap)
12521254
self.output(*pathops)
12531255
self.output(Op.paint_path(False, fillp, strokep))
12541256
self.endStream()
@@ -1474,7 +1476,8 @@ def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None)
14741476

14751477
output = self.file.output
14761478
marker = self.file.markerObject(
1477-
marker_path, marker_trans, fillp, strokep, self.gc._linewidth)
1479+
marker_path, marker_trans, fillp, strokep, self.gc._linewidth,
1480+
gc.get_joinstyle(), gc.get_capstyle())
14781481

14791482
output(Op.gsave)
14801483
lastx, lasty = 0, 0

lib/matplotlib/backends/backend_ps.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,11 @@ def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None)
591591

592592
# construct the generic marker command:
593593
ps_cmd = ['/o {', 'gsave', 'newpath', 'translate'] # dont want the translate to be global
594+
jint = gc.get_joinstyle()
595+
ps_cmd.append('%d setlinejoin' % jint)
596+
cint = gc.get_capstyle()
597+
ps_cmd.append('%d setlinecap' % cint)
598+
594599
ps_cmd.append(self._convert_path(marker_path, marker_trans,
595600
simplify=False))
596601

lib/matplotlib/backends/backend_svg.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ def _write_hatches(self):
374374
writer.end(u'pattern')
375375
writer.end(u'defs')
376376

377-
def _get_style(self, gc, rgbFace):
377+
def _get_style_dict(self, gc, rgbFace):
378378
"""
379379
return the style string. style is generated from the
380380
GraphicsContext and rgbFace
@@ -407,7 +407,10 @@ def _get_style(self, gc, rgbFace):
407407
if gc.get_capstyle() != 'projecting':
408408
attrib[u'stroke-linecap'] = _capstyle_d[gc.get_capstyle()]
409409

410-
return generate_css(attrib)
410+
return attrib
411+
412+
def _get_style(self, gc, rgbFace):
413+
return generate_css(self._get_style_dict(gc, rgbFace))
411414

412415
def _get_clip(self, gc):
413416
cliprect = gc.get_clip_rectangle()
@@ -540,12 +543,18 @@ def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None)
540543
marker_path,
541544
marker_trans + Affine2D().scale(1.0, -1.0),
542545
simplify=False)
543-
dictkey = (path_data)
546+
style = self._get_style_dict(gc, rgbFace)
547+
dictkey = (path_data, generate_css(style))
544548
oid = self._markers.get(dictkey)
549+
for key in style.keys():
550+
if not key.startswith('stroke'):
551+
del style[key]
552+
style = generate_css(style)
553+
545554
if oid is None:
546555
oid = self._make_id(u'm', dictkey)
547556
writer.start(u'defs')
548-
writer.element(u'path', id=oid, d=path_data)
557+
writer.element(u'path', id=oid, d=path_data, style=style)
549558
writer.end(u'defs')
550559
self._markers[dictkey] = oid
551560

@@ -576,15 +585,9 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms,
576585
master_transform, paths, all_transforms)):
577586
transform = Affine2D(transform.get_matrix()).scale(1.0, -1.0)
578587
d = self._convert_path(path, transform, simplify=False)
579-
<<<<<<< HEAD
580588
oid = u'C%x_%x_%s' % (self._path_collection_id, i,
581589
self._make_id(u'', d))
582590
writer.element(u'path', id=oid, d=d)
583-
=======
584-
oid = 'C%x_%x_%s' % (self._path_collection_id, i,
585-
self._make_id('', d))
586-
writer.element('path', id=oid, d=d)
587-
>>>>>>> Prevent duplicate marker ids
588591
path_codes.append(oid)
589592
writer.end(u'defs')
590593

lib/matplotlib/lines.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,8 @@ def draw(self, renderer):
542542
if type(snap) == float:
543543
snap = renderer.points_to_pixels(self._markersize) >= snap
544544
gc.set_snap(snap)
545+
gc.set_joinstyle(marker.get_joinstyle())
546+
gc.set_capstyle(marker.get_capstyle())
545547
marker_path = marker.get_path()
546548
marker_trans = marker.get_transform()
547549
w = renderer.points_to_pixels(self._markersize)

lib/matplotlib/markers.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ def _recache(self):
118118
self._alt_path = None
119119
self._alt_transform = None
120120
self._snap_threshold = None
121+
self._joinstyle = 'round'
122+
self._capstyle = 'butt'
121123
self._filled = True
122124
self._marker_function()
123125

@@ -136,6 +138,12 @@ def set_fillstyle(self, fillstyle):
136138
self._fillstyle = fillstyle
137139
self._recache()
138140

141+
def get_joinstyle(self):
142+
return self._joinstyle
143+
144+
def get_capstyle(self):
145+
return self._capstyle
146+
139147
def get_marker(self):
140148
return self._marker
141149

@@ -201,11 +209,14 @@ def _set_tuple_marker(self):
201209
symstyle = marker[1]
202210
if symstyle == 0:
203211
self._path = Path.unit_regular_polygon(numsides)
212+
self._joinstyle = 'miter'
204213
elif symstyle == 1:
205214
self._path = Path.unit_regular_star(numsides)
215+
self._joinstyle = 'bevel'
206216
elif symstyle == 2:
207217
self._path = Path.unit_regular_asterisk(numsides)
208218
self._filled = False
219+
self._joinstyle = 'bevel'
209220
elif symstyle == 3:
210221
self._path = Path.unit_circle()
211222
self._transform = Affine2D().scale(0.5).rotate_deg(rotation)
@@ -269,8 +280,10 @@ def _set_circle(self, reduction = 1.0):
269280

270281
def _set_pixel(self):
271282
self._path = Path.unit_rectangle()
272-
self._transform = Affine2D().translate(-0.5, 0.5)
283+
self._transform = Affine2D().translate(-0.5, -0.5) \
284+
.scale(0.5, 0.5).translate(0.5, 0.5)
273285
self._snap_threshold = False
286+
self._joinstyle = 'miter'
274287

275288
def _set_point(self):
276289
self._set_circle(reduction = self._point_size_reduction)
@@ -319,6 +332,8 @@ def _set_triangle(self, rot, skip):
319332

320333
self._alt_transform = self._transform
321334

335+
self._joinstyle = 'miter'
336+
322337
def _set_triangle_up(self):
323338
return self._set_triangle(0.0, 0)
324339

@@ -351,6 +366,8 @@ def _set_square(self):
351366
self._transform.rotate_deg(rotate)
352367
self._alt_transform = self._transform
353368

369+
self._joinstyle = 'miter'
370+
354371
def _set_diamond(self):
355372
self._transform = Affine2D().translate(-0.5, -0.5).rotate_deg(45)
356373
self._snap_threshold = 5.0
@@ -369,6 +386,8 @@ def _set_diamond(self):
369386
self._transform.rotate_deg(rotate)
370387
self._alt_transform = self._transform
371388

389+
self._joinstyle = 'miter'
390+
372391
def _set_thin_diamond(self):
373392
self._set_diamond()
374393
self._transform.scale(0.6, 1.0)
@@ -403,6 +422,8 @@ def _set_pentagon(self):
403422
self._alt_path = mpath_alt
404423
self._alt_transform = self._transform
405424

425+
self._joinstyle = 'miter'
426+
406427
def _set_star(self):
407428
self._transform = Affine2D().scale(0.5)
408429
self._snap_threshold = 5.0
@@ -432,6 +453,8 @@ def _set_star(self):
432453
self._alt_path = mpath_alt
433454
self._alt_transform = self._transform
434455

456+
self._joinstyle = 'bevel'
457+
435458
def _set_hexagon1(self):
436459
self._transform = Affine2D().scale(0.5)
437460
self._snap_threshold = 5.0
@@ -464,6 +487,8 @@ def _set_hexagon1(self):
464487
self._alt_path = mpath_alt
465488
self._alt_transform = self._transform
466489

490+
self._joinstyle = 'miter'
491+
467492
def _set_hexagon2(self):
468493
self._transform = Affine2D().scale(0.5).rotate_deg(30)
469494
self._snap_threshold = 5.0
@@ -496,6 +521,8 @@ def _set_hexagon2(self):
496521
self._alt_path = mpath_alt
497522
self._alt_transform = self._transform
498523

524+
self._joinstyle = 'miter'
525+
499526
def _set_octagon(self):
500527
self._transform = Affine2D().scale(0.5)
501528
self._snap_threshold = 5.0
@@ -520,6 +547,8 @@ def _set_octagon(self):
520547
self._path = self._alt_path = half
521548
self._alt_transform = self._transform.frozen().rotate_deg(180.0)
522549

550+
self._joinstyle = 'miter'
551+
523552
_line_marker_path = Path([[0.0, -1.0], [0.0, 1.0]])
524553
def _set_vline(self):
525554
self._transform = Affine2D().scale(0.5)
@@ -605,24 +634,28 @@ def _set_caretdown(self):
605634
self._snap_threshold = 3.0
606635
self._filled = False
607636
self._path = self._caret_path
637+
self._joinstyle = 'miter'
608638

609639
def _set_caretup(self):
610640
self._transform = Affine2D().scale(0.5).rotate_deg(180)
611641
self._snap_threshold = 3.0
612642
self._filled = False
613643
self._path = self._caret_path
644+
self._joinstyle = 'miter'
614645

615646
def _set_caretleft(self):
616647
self._transform = Affine2D().scale(0.5).rotate_deg(270)
617648
self._snap_threshold = 3.0
618649
self._filled = False
619650
self._path = self._caret_path
651+
self._joinstyle = 'miter'
620652

621653
def _set_caretright(self):
622654
self._transform = Affine2D().scale(0.5).rotate_deg(90)
623655
self._snap_threshold = 3.0
624656
self._filled = False
625657
self._path = self._caret_path
658+
self._joinstyle = 'miter'
626659

627660
_x_path = Path([[-1.0, -1.0], [1.0, 1.0],
628661
[-1.0, 1.0], [1.0, -1.0]],

0 commit comments

Comments
 (0)