Create a radar chart with `num_vars` axes. This function creates a RadarAxes projection and registers it. Parameters ---------- num_vars : int Number of variables for radar chart. frame : {'circle' | 'polygon'} Shape of frame surround
(num_vars, frame='circle')
| 435 | from matplotlib.projections import register_projection |
| 436 | |
| 437 | def radar_factory(num_vars, frame='circle'): |
| 438 | """Create a radar chart with `num_vars` axes. |
| 439 | |
| 440 | This function creates a RadarAxes projection and registers it. |
| 441 | |
| 442 | Parameters |
| 443 | ---------- |
| 444 | num_vars : int |
| 445 | Number of variables for radar chart. |
| 446 | frame : {'circle' | 'polygon'} |
| 447 | Shape of frame surrounding axes. |
| 448 | |
| 449 | """ |
| 450 | # calculate evenly-spaced axis angles |
| 451 | theta = np.linspace(0, 2 * np.pi, num_vars, endpoint=False) |
| 452 | |
| 453 | def draw_poly_patch(self): |
| 454 | # rotate theta such that the first axis is at the top |
| 455 | verts = unit_poly_verts(theta + np.pi / 2) |
| 456 | return plt.Polygon(verts, closed=True, edgecolor='k') |
| 457 | |
| 458 | def draw_circle_patch(self): |
| 459 | # unit circle centered on (0.5, 0.5) |
| 460 | return plt.Circle((0.5, 0.5), 0.5) |
| 461 | |
| 462 | patch_dict = {'polygon': draw_poly_patch, 'circle': draw_circle_patch} |
| 463 | if frame not in patch_dict: |
| 464 | raise ValueError('unknown value for `frame`: %s' % frame) |
| 465 | |
| 466 | class RadarAxes(PolarAxes): |
| 467 | |
| 468 | name = 'radar' |
| 469 | # use 1 line segment to connect specified points |
| 470 | RESOLUTION = 1 |
| 471 | # define draw_frame method |
| 472 | draw_patch = patch_dict[frame] |
| 473 | |
| 474 | def __init__(self, *args, **kwargs): |
| 475 | super(RadarAxes, self).__init__(*args, **kwargs) |
| 476 | # rotate plot such that the first axis is at the top |
| 477 | self.set_theta_zero_location('N') |
| 478 | |
| 479 | def fill(self, *args, **kwargs): |
| 480 | """Override fill so that line is closed by default""" |
| 481 | closed = kwargs.pop('closed', True) |
| 482 | return super(RadarAxes, self).fill(closed=closed, *args, **kwargs) |
| 483 | |
| 484 | def plot(self, *args, **kwargs): |
| 485 | """Override plot so that line is closed by default""" |
| 486 | lines = super(RadarAxes, self).plot(*args, **kwargs) |
| 487 | for line in lines: |
| 488 | self._close_line(line) |
| 489 | |
| 490 | def _close_line(self, line): |
| 491 | x, y = line.get_data() |
| 492 | # FIXME: markers at x[0], y[0] get doubled-up |
| 493 | if x[0] != x[-1]: |
| 494 | x = np.concatenate((x, [x[0]])) |