99
1010import numpy as np
1111import matplotlib .pyplot as plt
12- from matplotlib .patches import Circle , Rectangle
12+ from matplotlib .patches import Circle
1313from matplotlib .patheffects import withStroke
1414from matplotlib .ticker import AutoMinorLocator , MultipleLocator
1515
16- royal_blue = "#002082"
1716royal_blue = [0 , 20 / 256 , 82 / 256 ]
1817
18+
1919# make the figure
2020
2121np .random .seed (19680801 )
2525Y2 = 1 + np .cos (1 + X / 0.75 )/ 2
2626Y3 = np .random .uniform (Y1 , Y2 , len (X ))
2727
28- fig = plt .figure (figsize = (8 , 8 ), facecolor = '1' )
29- marg = 0.15
30- ax = fig .add_axes ([marg , marg , 1 - 1.8 * marg , 1 - 1.8 * marg ], aspect = 1 ,
31- facecolor = '1' )
32-
33-
34- def minor_tick (x , pos ):
35- if not x % 1.0 :
36- return ""
37- return f"{ x :.2f} "
28+ fig = plt .figure (figsize = (7.5 , 7.5 ))
29+ ax = fig .add_axes ([0.2 , 0.17 , 0.68 , 0.7 ], aspect = 1 )
3830
3931ax .xaxis .set_major_locator (MultipleLocator (1.000 ))
4032ax .xaxis .set_minor_locator (AutoMinorLocator (4 ))
4133ax .yaxis .set_major_locator (MultipleLocator (1.000 ))
4234ax .yaxis .set_minor_locator (AutoMinorLocator (4 ))
43- # FuncFormatter is created and used automatically
44- ax .xaxis .set_minor_formatter (minor_tick )
35+ ax .xaxis .set_minor_formatter ("{x:.2f}" )
4536
4637ax .set_xlim (0 , 4 )
4738ax .set_ylim (0 , 4 )
4839
49- ax .tick_params (which = 'major' , width = 1.0 , labelsize = 14 )
50- ax .tick_params (which = 'major' , length = 10 , labelsize = 14 )
51- ax .tick_params (which = 'minor' , width = 1.0 , labelsize = 10 )
52- ax .tick_params (which = 'minor' , length = 5 , labelsize = 10 , labelcolor = '0.25' )
40+ ax .tick_params (which = 'major' , width = 1.0 , length = 10 , labelsize = 14 )
41+ ax .tick_params (which = 'minor' , width = 1.0 , length = 5 , labelsize = 10 ,
42+ labelcolor = '0.25' )
5343
5444ax .grid (linestyle = "--" , linewidth = 0.5 , color = '.25' , zorder = - 10 )
5545
@@ -62,92 +52,54 @@ def minor_tick(x, pos):
6252ax .set_title ("Anatomy of a figure" , fontsize = 20 , verticalalignment = 'bottom' )
6353ax .set_xlabel ("x Axis label" , fontsize = 14 )
6454ax .set_ylabel ("y Axis label" , fontsize = 14 )
65-
6655ax .legend (loc = "upper right" , fontsize = 14 )
6756
68- # Annotate the figure
6957
58+ # Annotate the figure
7059
71- def just_circle (x , y , radius = 0.15 ):
72- c = Circle ((x , y ), radius , clip_on = False , zorder = 10 , linewidth = 2.5 ,
60+ def annotate (x , y , text , code ):
61+ # Circle marker
62+ c = Circle ((x , y ), radius = 0.15 , clip_on = False , zorder = 10 , linewidth = 2.5 ,
7363 edgecolor = royal_blue + [0.6 ], facecolor = 'none' ,
74- path_effects = [withStroke (linewidth = 7 , foreground = ( 1 , 1 , 1 , 1 ) )])
64+ path_effects = [withStroke (linewidth = 7 , foreground = 'white' )])
7565 ax .add_artist (c )
7666
77-
78- def text (x , y , text ):
79- ax .text (x , y , text , zorder = 100 ,
80- ha = 'center' , va = 'top' , weight = 'bold' , color = royal_blue ,
81- style = 'italic' , fontfamily = 'monospace' ,
82- path_effects = [withStroke (linewidth = 7 , foreground = (1 , 1 , 1 , 1 ))])
83-
84-
85- def code (x , y , text ):
86- ax .text (x , y , text , zorder = 100 ,
87- ha = 'center' , va = 'top' , weight = 'normal' , color = '0.0' ,
88- fontfamily = 'Courier New' , fontsize = 'medium' ,
89- path_effects = [withStroke (linewidth = 7 , foreground = (1 , 1 , 1 , 1 ))])
90-
91-
92- def circle (x , y , txt , cde , radius = 0.15 ):
93- just_circle (x , y , radius = radius )
94- text (x , y - 0.2 , txt )
95- code (x , y - 0.33 , cde )
96-
97- # Minor tick label
98- circle (3.25 , - 0.10 , "Minor tick label" ,
99- "ax.xaxis.set_minor_formatter" )
100-
101- # Major tick
102- circle (- 0.03 , 1.05 , "Major tick" , "ax.yaxis.set_major_locator" )
103-
104- # Minor tick
105- y = 3.75
106- circle (0.00 , 3.75 , "Minor tick" , "ax.yaxis.set_minor_locator" )
107-
108- # Major tick label
109- circle (- 0.15 , 3.00 , "Major tick label" , "ax.yaxis.set_major_formatter" )
110-
111- # X Label
112- circle (1.90 , - 0.32 , "xlabel" , "ax.set_xlabel" )
113-
114- # Y Label
115- circle (- 0.27 , 1.68 , "ylabel" , "ax.set_ylabel" )
116-
117- # Title
118- circle (1.58 , 4.13 , "Title" , "ax.set_title" )
119-
120- # Blue plot
121- circle (1.75 , 2.80 , "Line" , "ax.plot" )
122-
123- # Scatter plot
124- circle (2.25 , 1.54 , "Markers" , "ax.scatter" )
125-
126- # Grid
127- circle (3.00 , 3.00 , "Grid" , "ax.grid" )
128-
129- # Legend
130- circle (3.60 , 3.65 , "Legend" , "ax.legend" )
131-
132- # Axes
133- circle (2.5 , 0.55 , "Axes" , "fig.subplots" )
134-
135- # Figure
136- circle (4.185 , 4.3 , "Figure" , "plt.figure" )
137-
138- # x Axis
139- circle (0.65 , 0.01 , "x Axis" , "ax.xaxis" )
140-
141- # y Axis
142- circle (0 , 0.44 , "y Axis" , "ax.yaxis" )
143-
144- # Spine
145- circle (4.0 , 0.7 , "Spine" , "ax.spines" )
146-
147- # frame around figure...
148- fig .add_artist (Rectangle ((0 , 0 ), width = 1 , height = 1 , facecolor = 'none' ,
149- edgecolor = '0.5' , linewidth = 10 ))
150-
67+ # use path_effects as a background for the texts
68+ # draw the path_effects and the colored text separately so that the
69+ # path_effects cannot clip other texts
70+ for path_effects in [[withStroke (linewidth = 7 , foreground = 'white' )], []]:
71+ color = 'white' if path_effects else royal_blue
72+ ax .text (x , y - 0.2 , text , zorder = 100 ,
73+ ha = 'center' , va = 'top' , weight = 'bold' , color = color ,
74+ style = 'italic' , fontfamily = 'Courier New' ,
75+ path_effects = path_effects )
76+
77+ color = 'white' if path_effects else 'black'
78+ ax .text (x , y - 0.33 , code , zorder = 100 ,
79+ ha = 'center' , va = 'top' , weight = 'normal' , color = color ,
80+ fontfamily = 'monospace' , fontsize = 'medium' ,
81+ path_effects = path_effects )
82+
83+
84+ annotate (3.5 , - 0.13 , "Minor tick label" , "ax.xaxis.set_minor_formatter" )
85+ annotate (- 0.03 , 1.0 , "Major tick" , "ax.yaxis.set_major_locator" )
86+ annotate (0.00 , 3.75 , "Minor tick" , "ax.yaxis.set_minor_locator" )
87+ annotate (- 0.15 , 3.00 , "Major tick label" , "ax.yaxis.set_major_formatter" )
88+ annotate (1.68 , - 0.39 , "xlabel" , "ax.set_xlabel" )
89+ annotate (- 0.38 , 1.67 , "ylabel" , "ax.set_ylabel" )
90+ annotate (1.52 , 4.15 , "Title" , "ax.set_title" )
91+ annotate (1.75 , 2.80 , "Line" , "ax.plot" )
92+ annotate (2.25 , 1.54 , "Markers" , "ax.scatter" )
93+ annotate (3.00 , 3.00 , "Grid" , "ax.grid" )
94+ annotate (3.60 , 3.58 , "Legend" , "ax.legend" )
95+ annotate (2.5 , 0.55 , "Axes" , "fig.subplots" )
96+ annotate (4 , 4.5 , "Figure" , "plt.figure" )
97+ annotate (0.65 , 0.01 , "x Axis" , "ax.xaxis" )
98+ annotate (0 , 0.36 , "y Axis" , "ax.yaxis" )
99+ annotate (4.0 , 0.7 , "Spine" , "ax.spines" )
100+
101+ # frame around figure
102+ fig .patch .set (linewidth = 4 , edgecolor = '0.5' )
151103plt .show ()
152104
153105
0 commit comments