Skip to content

Commit b914ed6

Browse files
committed
Filled + and x markers
The rationale for the addition of these symbols is; to allow a grammar based plotting package to conveniently use the common plotting symbols (circle, square, triangle, plus and x) and not have to deal with some of them not being fillable.
1 parent f3b6c4e commit b914ed6

File tree

5 files changed

+98
-2
lines changed

5 files changed

+98
-2
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Filled ``+`` and ``x`` markers
2+
------------------------------
3+
4+
New fillable *plus* and *x* markers have been added. See
5+
the :mod:`~matplotlib.markers` module and
6+
:ref:`marker reference <lines_bars_and_markers-marker_reference>`
7+
examples.

lib/matplotlib/markers.py

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
"d" thin_diamond
3232
"|" vline
3333
"_" hline
34+
"P" plus (filled)
35+
"X" x (filled)
3436
TICKLEFT tickleft
3537
TICKRIGHT tickright
3638
TICKUP tickup
@@ -126,6 +128,8 @@ class MarkerStyle(object):
126128
'd': 'thin_diamond',
127129
'|': 'vline',
128130
'_': 'hline',
131+
'P': 'plus_filled',
132+
'X': 'x_filled',
129133
TICKLEFT: 'tickleft',
130134
TICKRIGHT: 'tickright',
131135
TICKUP: 'tickup',
@@ -147,7 +151,8 @@ class MarkerStyle(object):
147151
# Just used for informational purposes. is_filled()
148152
# is calculated in the _set_* functions.
149153
filled_markers = (
150-
'o', 'v', '^', '<', '>', '8', 's', 'p', '*', 'h', 'H', 'D', 'd')
154+
'o', 'v', '^', '<', '>', '8', 's', 'p', '*', 'h', 'H', 'D', 'd',
155+
'P', 'X')
151156

152157
fillstyles = ('full', 'left', 'right', 'bottom', 'top', 'none')
153158
_half_fillstyles = ('left', 'right', 'bottom', 'top')
@@ -828,3 +833,87 @@ def _set_x(self):
828833
self._snap_threshold = 3.0
829834
self._filled = False
830835
self._path = self._x_path
836+
837+
_plus_filled_path = Path([(1/3, 0), (2/3, 0), (2/3, 1/3),
838+
(1, 1/3), (1, 2/3), (2/3, 2/3),
839+
(2/3, 1), (1/3, 1), (1/3, 2/3),
840+
(0, 2/3), (0, 1/3), (1/3, 1/3),
841+
(1/3, 0)],
842+
[Path.MOVETO, Path.LINETO, Path.LINETO,
843+
Path.LINETO, Path.LINETO, Path.LINETO,
844+
Path.LINETO, Path.LINETO, Path.LINETO,
845+
Path.LINETO, Path.LINETO, Path.LINETO,
846+
Path.CLOSEPOLY])
847+
848+
_plus_filled_path_t = Path([(1, 1/2), (1, 2/3), (2/3, 2/3),
849+
(2/3, 1), (1/3, 1), (1/3, 2/3),
850+
(0, 2/3), (0, 1/2), (1, 1/2)],
851+
[Path.MOVETO, Path.LINETO, Path.LINETO,
852+
Path.LINETO, Path.LINETO, Path.LINETO,
853+
Path.LINETO, Path.LINETO,
854+
Path.CLOSEPOLY])
855+
856+
def _set_plus_filled(self):
857+
self._transform = Affine2D().translate(-0.5, -0.5)
858+
self._snap_threshold = 5.0
859+
self._joinstyle = 'miter'
860+
fs = self.get_fillstyle()
861+
if not self._half_fill():
862+
self._path = self._plus_filled_path
863+
else:
864+
# Rotate top half path to support all partitions
865+
if fs == 'top':
866+
rotate, rotate_alt = 0, 180
867+
elif fs == 'bottom':
868+
rotate, rotate_alt = 180, 0
869+
elif fs == 'left':
870+
rotate, rotate_alt = 90, 270
871+
else:
872+
rotate, rotate_alt = 270, 90
873+
874+
self._path = self._plus_filled_path_t
875+
self._alt_path = self._plus_filled_path_t
876+
self._alt_transform = Affine2D().translate(-0.5, -0.5)
877+
self._transform.rotate_deg(rotate)
878+
self._alt_transform.rotate_deg(rotate_alt)
879+
880+
_x_filled_path = Path([(0.25, 0), (0.5, 0.25), (0.75, 0), (1, 0.25),
881+
(0.75, 0.5), (1, 0.75), (0.75, 1), (0.5, 0.75),
882+
(0.25, 1), (0, 0.75), (0.25, 0.5), (0, 0.25),
883+
(0.25, 0)],
884+
[Path.MOVETO, Path.LINETO, Path.LINETO,
885+
Path.LINETO, Path.LINETO, Path.LINETO,
886+
Path.LINETO, Path.LINETO, Path.LINETO,
887+
Path.LINETO, Path.LINETO, Path.LINETO,
888+
Path.CLOSEPOLY])
889+
890+
_x_filled_path_t = Path([(0.75, 0.5), (1, 0.75), (0.75, 1),
891+
(0.5, 0.75), (0.25, 1), (0, 0.75),
892+
(0.25, 0.5), (0.75, 0.5)],
893+
[Path.MOVETO, Path.LINETO, Path.LINETO,
894+
Path.LINETO, Path.LINETO, Path.LINETO,
895+
Path.LINETO, Path.CLOSEPOLY])
896+
897+
def _set_x_filled(self):
898+
self._transform = Affine2D().translate(-0.5, -0.5)
899+
self._snap_threshold = 5.0
900+
self._joinstyle = 'miter'
901+
fs = self.get_fillstyle()
902+
if not self._half_fill():
903+
self._path = self._x_filled_path
904+
else:
905+
# Rotate top half path to support all partitions
906+
if fs == 'top':
907+
rotate, rotate_alt = 0, 180
908+
elif fs == 'bottom':
909+
rotate, rotate_alt = 180, 0
910+
elif fs == 'left':
911+
rotate, rotate_alt = 90, 270
912+
else:
913+
rotate, rotate_alt = 270, 90
914+
915+
self._path = self._x_filled_path_t
916+
self._alt_path = self._x_filled_path_t
917+
self._alt_transform = Affine2D().translate(-0.5, -0.5)
918+
self._transform.rotate_deg(rotate)
919+
self._alt_transform.rotate_deg(rotate_alt)
1.15 KB
Loading
3.48 KB
Loading

lib/matplotlib/tests/test_lines.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ def test_marker_fill_styles():
180180
markeredgewidth=2)
181181

182182
ax.set_ylim([0, 7.5])
183-
ax.set_xlim([-5, 135])
183+
ax.set_xlim([-5, 155])
184184

185185

186186
@image_comparison(baseline_images=['scaled_lines'], style='default')

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy