Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit824ce2b

Browse files
marker-transforms
1 parent71163e9 commit824ce2b

File tree

4 files changed

+117
-14
lines changed

4 files changed

+117
-14
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Allow for custom marker scaling
2+
-------------------------------
3+
`~.markers.MarkerStyle` gained a keyword argument *normalization*, which may be
4+
set to *"none"* to allow for custom paths to not be scaled.::
5+
6+
MarkerStyle(Path(...), normalization="none")
7+
8+
`~.markers.MarkerStyle` also gained a `~.markers.MarkerStyle.set_transform`
9+
method to set affine transformations to existing markers.::
10+
11+
m = MarkerStyle("d")
12+
m.set_transform(m.get_transform() + Affine2D().rotate_deg(30))

‎examples/lines_bars_and_markers/scatter_piecharts.py

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@
33
Scatter plot with pie chart markers
44
===================================
55
6-
This example makes custom 'pie charts' as the markers for a scatter plot.
7-
8-
Thanks to Manuel Metz for the example.
6+
This example shows two methods to make custom 'pie charts' as the markers
7+
for a scatter plot.
98
"""
109

10+
##########################################################################
11+
# Manually creating marker vertices
12+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
13+
#
14+
1115
importnumpyasnp
1216
importmatplotlib.pyplotasplt
1317

14-
# first define the ratios
18+
# first define thecumulativeratios
1519
r1=0.2# 20%
1620
r2=r1+0.4# 40%
1721

@@ -36,10 +40,55 @@
3640
s3=np.abs(xy3).max()
3741

3842
fig,ax=plt.subplots()
39-
ax.scatter(range(3),range(3),marker=xy1,s=s1**2*sizes,facecolor='blue')
40-
ax.scatter(range(3),range(3),marker=xy2,s=s2**2*sizes,facecolor='green')
41-
ax.scatter(range(3),range(3),marker=xy3,s=s3**2*sizes,facecolor='red')
43+
ax.scatter(range(3),range(3),marker=xy1,s=s1**2*sizes,facecolor='C0')
44+
ax.scatter(range(3),range(3),marker=xy2,s=s2**2*sizes,facecolor='C1')
45+
ax.scatter(range(3),range(3),marker=xy3,s=s3**2*sizes,facecolor='C2')
46+
47+
plt.show()
48+
49+
50+
##########################################################################
51+
# Using wedges as markers
52+
# ~~~~~~~~~~~~~~~~~~~~~~~
53+
#
54+
# An alternative is to create custom markers from the `~.path.Path` of a
55+
# `~.patches.Wedge`, which might be more versatile.
56+
#
57+
58+
importnumpyasnp
59+
importmatplotlib.pyplotasplt
60+
frommatplotlib.patchesimportWedge
61+
frommatplotlib.markersimportMarkerStyle
62+
63+
# first define the ratios
64+
r1=0.2# 20%
65+
r2=r1+0.3# 50%
66+
r3=1-r1-r2# 30%
67+
68+
69+
defmarkers_from_ratios(ratios,width=1):
70+
markers= []
71+
angles=360*np.concatenate(([0],np.cumsum(ratios)))
72+
foriinrange(len(angles)-1):
73+
# create a Wedge within the unit square in between the given angles...
74+
w=Wedge((0,0),0.5,angles[i],angles[i+1],width=width/2)
75+
# ... and create a custom Marker from its path.
76+
markers.append(MarkerStyle(w.get_path(),normalization="none"))
77+
returnmarkers
78+
79+
# define some sizes of the scatter marker
80+
sizes=np.array([100,200,400,800])
81+
# collect the markers and some colors
82+
markers=markers_from_ratios([r1,r2,r3],width=0.6)
83+
colors=plt.cm.tab10.colors[:len(markers)]
84+
85+
fig,ax=plt.subplots()
86+
87+
formarker,colorinzip(markers,colors):
88+
ax.scatter(range(len(sizes)),range(len(sizes)),marker=marker,s=sizes,
89+
edgecolor="none",facecolor=color)
4290

91+
ax.margins(0.1)
4392
plt.show()
4493

4594
#############################################################################
@@ -55,3 +104,5 @@
55104
importmatplotlib
56105
matplotlib.axes.Axes.scatter
57106
matplotlib.pyplot.scatter
107+
matplotlib.patches.Wedge
108+
matplotlib.markers.MarkerStyle

‎lib/matplotlib/markers.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ class MarkerStyle:
201201
# TODO: Is this ever used as a non-constant?
202202
_point_size_reduction=0.5
203203

204-
def__init__(self,marker=None,fillstyle=None):
204+
def__init__(self,marker=None,fillstyle=None,*,
205+
normalization="classic"):
205206
"""
206207
Attributes
207208
----------
@@ -213,12 +214,23 @@ def __init__(self, marker=None, fillstyle=None):
213214
214215
Parameters
215216
----------
216-
marker : str or array-like, optional, default: None
217+
marker : str, array-like, `~.path.Path`, or `~.markers.MarkerStyle`,\
218+
default: None
217219
See the descriptions of possible markers in the module docstring.
218220
219221
fillstyle : str, optional, default: 'full'
220222
'full', 'left", 'right', 'bottom', 'top', 'none'
223+
224+
normalization : str, {'classic', 'none'}, optional, default: "classic"
225+
The normalization of the marker size. Only applies to custom paths
226+
that are provided as array of vertices or `~.path.Path`.
227+
Can take two values:
228+
*'classic'*, being the default, makes sure the marker path is
229+
normalized to fit within a unit-square by affine scaling.
230+
*'none'*, in which case no scaling is performed on the marker path.
221231
"""
232+
cbook._check_in_list(["classic","none"],normalization=normalization)
233+
self._normalize=normalization
222234
self._marker_function=None
223235
self.set_fillstyle(fillstyle)
224236
self.set_marker(marker)
@@ -303,6 +315,13 @@ def get_path(self):
303315
defget_transform(self):
304316
returnself._transform.frozen()
305317

318+
defset_transform(self,transform):
319+
"""
320+
Sets the transform of the marker. This is the transform by which the
321+
marker path is transformed.
322+
"""
323+
self._transform=transform
324+
306325
defget_alt_path(self):
307326
returnself._alt_path
308327

@@ -316,8 +335,9 @@ def _set_nothing(self):
316335
self._filled=False
317336

318337
def_set_custom_marker(self,path):
319-
rescale=np.max(np.abs(path.vertices))# max of x's and y's.
320-
self._transform=Affine2D().scale(0.5/rescale)
338+
ifself._normalize=="classic":
339+
rescale=np.max(np.abs(path.vertices))# max of x's and y's.
340+
self._transform=Affine2D().scale(0.5/rescale)
321341
self._path=path
322342

323343
def_set_path_marker(self):
@@ -350,8 +370,6 @@ def _set_tuple_marker(self):
350370
def_set_mathtext_path(self):
351371
"""
352372
Draws mathtext markers '$...$' using TextPath object.
353-
354-
Submitted by tcb
355373
"""
356374
frommatplotlib.textimportTextPath
357375

‎lib/matplotlib/tests/test_marker.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
importmatplotlib.pyplotasplt
33
frommatplotlibimportmarkers
44
frommatplotlib.pathimportPath
5-
frommatplotlib.testing.decoratorsimportcheck_figures_equal
5+
frommatplotlib.transformsimportAffine2D
66

7+
frommatplotlib.testing.decoratorsimportcheck_figures_equal
78
importpytest
89

910

@@ -133,3 +134,24 @@ def draw_ref_marker(y, style, size):
133134

134135
ax_test.set(xlim=(-0.5,1.5),ylim=(-0.5,1.5))
135136
ax_ref.set(xlim=(-0.5,1.5),ylim=(-0.5,1.5))
137+
138+
139+
@check_figures_equal(extensions=["png"])
140+
deftest_marker_normalization(fig_test,fig_ref):
141+
plt.style.use("mpl20")
142+
143+
ax=fig_ref.subplots()
144+
ax.margins(0.3)
145+
ax.scatter([0,1], [0,0],s=400,marker="s",c="C2")
146+
147+
ax=fig_test.subplots()
148+
ax.margins(0.3)
149+
# test normalize
150+
p=Path([[0,0], [1,0], [1,1], [0,1], [0,0]],closed=True)
151+
p1=p.transformed(Affine2D().translate(-.5,-.5).scale(20))
152+
m1=markers.MarkerStyle(p1,normalization="none")
153+
ax.scatter([0], [0],s=1,marker=m1,c="C2")
154+
# test transform
155+
m2=markers.MarkerStyle("s")
156+
m2.set_transform(m2.get_transform()+Affine2D().scale(20))
157+
ax.scatter([1], [0],s=1,marker=m2,c="C2")

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp