Skip to content

Commit 2d2d3e5

Browse files
authored
Merge pull request #12492 from anntzer/radar
Simplify radar_chart example.
2 parents 2980184 + 1ddf8d6 commit 2d2d3e5

File tree

1 file changed

+26
-40
lines changed

1 file changed

+26
-40
lines changed

examples/specialty_plots/radar_chart.py

+26-40
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@
1313
1414
.. [1] http://en.wikipedia.org/wiki/Radar_chart
1515
"""
16+
1617
import numpy as np
1718

1819
import matplotlib.pyplot as plt
20+
from matplotlib.patches import Circle, RegularPolygon
1921
from matplotlib.path import Path
20-
from matplotlib.spines import Spine
2122
from matplotlib.projections.polar import PolarAxes
2223
from matplotlib.projections import register_projection
24+
from matplotlib.spines import Spine
25+
from matplotlib.transforms import Affine2D
2326

2427

2528
def radar_factory(num_vars, frame='circle'):
@@ -38,26 +41,11 @@ def radar_factory(num_vars, frame='circle'):
3841
# calculate evenly-spaced axis angles
3942
theta = np.linspace(0, 2*np.pi, num_vars, endpoint=False)
4043

41-
def draw_poly_patch(self):
42-
# rotate theta such that the first axis is at the top
43-
verts = unit_poly_verts(theta + np.pi / 2)
44-
return plt.Polygon(verts, closed=True, edgecolor='k')
45-
46-
def draw_circle_patch(self):
47-
# unit circle centered on (0.5, 0.5)
48-
return plt.Circle((0.5, 0.5), 0.5)
49-
50-
patch_dict = {'polygon': draw_poly_patch, 'circle': draw_circle_patch}
51-
if frame not in patch_dict:
52-
raise ValueError('unknown value for `frame`: %s' % frame)
53-
5444
class RadarAxes(PolarAxes):
5545

5646
name = 'radar'
5747
# use 1 line segment to connect specified points
5848
RESOLUTION = 1
59-
# define draw_frame method
60-
draw_patch = patch_dict[frame]
6149

6250
def __init__(self, *args, **kwargs):
6351
super().__init__(*args, **kwargs)
@@ -86,39 +74,37 @@ def set_varlabels(self, labels):
8674
self.set_thetagrids(np.degrees(theta), labels)
8775

8876
def _gen_axes_patch(self):
89-
return self.draw_patch()
77+
# The Axes patch must be centered at (0.5, 0.5) and of radius 0.5
78+
# in axes coordinates.
79+
if frame == 'circle':
80+
return Circle((0.5, 0.5), 0.5)
81+
elif frame == 'polygon':
82+
return RegularPolygon((0.5, 0.5), num_vars,
83+
radius=.5, edgecolor="k")
84+
else:
85+
raise ValueError("unknown value for 'frame': %s" % frame)
9086

9187
def _gen_axes_spines(self):
9288
if frame == 'circle':
9389
return super()._gen_axes_spines()
94-
# The following is a hack to get the spines (i.e. the axes frame)
95-
# to draw correctly for a polygon frame.
96-
97-
# spine_type must be 'left', 'right', 'top', 'bottom', or `circle`.
98-
spine_type = 'circle'
99-
verts = unit_poly_verts(theta + np.pi / 2)
100-
# close off polygon by repeating first vertex
101-
verts.append(verts[0])
102-
path = Path(verts)
103-
104-
spine = Spine(self, spine_type, path)
105-
spine.set_transform(self.transAxes)
106-
return {'polar': spine}
90+
elif frame == 'polygon':
91+
# spine_type must be 'left'/'right'/'top'/'bottom'/'circle'.
92+
spine = Spine(axes=self,
93+
spine_type='circle',
94+
path=Path.unit_regular_polygon(num_vars))
95+
# unit_regular_polygon gives a polygon of radius 1 centered at
96+
# (0, 0) but we want a polygon of radius 0.5 centered at (0.5,
97+
# 0.5) in axes coordinates.
98+
spine.set_transform(Affine2D().scale(.5).translate(.5, .5)
99+
+ self.transAxes)
100+
return {'polar': spine}
101+
else:
102+
raise ValueError("unknown value for 'frame': %s" % frame)
107103

108104
register_projection(RadarAxes)
109105
return theta
110106

111107

112-
def unit_poly_verts(theta):
113-
"""Return vertices of polygon for subplot axes.
114-
115-
This polygon is circumscribed by a unit circle centered at (0.5, 0.5)
116-
"""
117-
x0, y0, r = [0.5] * 3
118-
verts = [(r*np.cos(t) + x0, r*np.sin(t) + y0) for t in theta]
119-
return verts
120-
121-
122108
def example_data():
123109
# The following data is from the Denver Aerosol Sources and Health study.
124110
# See doi:10.1016/j.atmosenv.2008.12.017

0 commit comments

Comments
 (0)