9
9
10
10
import numpy as np
11
11
import matplotlib .pyplot as plt
12
- from matplotlib .patches import Circle , Rectangle
12
+ from matplotlib .patches import Circle
13
13
from matplotlib .patheffects import withStroke
14
14
from matplotlib .ticker import AutoMinorLocator , MultipleLocator
15
15
16
- royal_blue = "#002082"
17
16
royal_blue = [0 , 20 / 256 , 82 / 256 ]
18
17
18
+
19
19
# make the figure
20
20
21
21
np .random .seed (19680801 )
25
25
Y2 = 1 + np .cos (1 + X / 0.75 )/ 2
26
26
Y3 = np .random .uniform (Y1 , Y2 , len (X ))
27
27
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 )
38
30
39
31
ax .xaxis .set_major_locator (MultipleLocator (1.000 ))
40
32
ax .xaxis .set_minor_locator (AutoMinorLocator (4 ))
41
33
ax .yaxis .set_major_locator (MultipleLocator (1.000 ))
42
34
ax .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}" )
45
36
46
37
ax .set_xlim (0 , 4 )
47
38
ax .set_ylim (0 , 4 )
48
39
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' )
53
43
54
44
ax .grid (linestyle = "--" , linewidth = 0.5 , color = '.25' , zorder = - 10 )
55
45
@@ -62,92 +52,54 @@ def minor_tick(x, pos):
62
52
ax .set_title ("Anatomy of a figure" , fontsize = 20 , verticalalignment = 'bottom' )
63
53
ax .set_xlabel ("x Axis label" , fontsize = 14 )
64
54
ax .set_ylabel ("y Axis label" , fontsize = 14 )
65
-
66
55
ax .legend (loc = "upper right" , fontsize = 14 )
67
56
68
- # Annotate the figure
69
57
58
+ # Annotate the figure
70
59
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 ,
73
63
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' )])
75
65
ax .add_artist (c )
76
66
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' )
151
103
plt .show ()
152
104
153
105
0 commit comments