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 surrounding Axes.
(num_vars, frame='circle')
| 26 | |
| 27 | |
| 28 | def radar_factory(num_vars, frame='circle'): |
| 29 | """ |
| 30 | Create a radar chart with `num_vars` Axes. |
| 31 | |
| 32 | This function creates a RadarAxes projection and registers it. |
| 33 | |
| 34 | Parameters |
| 35 | ---------- |
| 36 | num_vars : int |
| 37 | Number of variables for radar chart. |
| 38 | frame : {'circle', 'polygon'} |
| 39 | Shape of frame surrounding Axes. |
| 40 | |
| 41 | """ |
| 42 | # calculate evenly-spaced axis angles |
| 43 | theta = np.linspace(0, 2*np.pi, num_vars, endpoint=False) |
| 44 | |
| 45 | class RadarTransform(PolarAxes.PolarTransform): |
| 46 | |
| 47 | def transform_path_non_affine(self, path): |
| 48 | # Paths with non-unit interpolation steps correspond to gridlines, |
| 49 | # in which case we force interpolation (to defeat PolarTransform's |
| 50 | # autoconversion to circular arcs). |
| 51 | if path._interpolation_steps > 1: |
| 52 | path = path.interpolated(num_vars) |
| 53 | return Path(self.transform(path.vertices), path.codes) |
| 54 | |
| 55 | class RadarAxes(PolarAxes): |
| 56 | |
| 57 | name = 'radar' |
| 58 | PolarTransform = RadarTransform |
| 59 | |
| 60 | def __init__(self, *args, **kwargs): |
| 61 | super().__init__(*args, **kwargs) |
| 62 | # rotate plot such that the first axis is at the top |
| 63 | self.set_theta_zero_location('N') |
| 64 | |
| 65 | def fill(self, *args, closed=True, **kwargs): |
| 66 | """Override fill so that line is closed by default""" |
| 67 | return super().fill(closed=closed, *args, **kwargs) |
| 68 | |
| 69 | def plot(self, *args, **kwargs): |
| 70 | """Override plot so that line is closed by default""" |
| 71 | lines = super().plot(*args, **kwargs) |
| 72 | for line in lines: |
| 73 | self._close_line(line) |
| 74 | |
| 75 | def _close_line(self, line): |
| 76 | x, y = line.get_data() |
| 77 | # FIXME: markers at x[0], y[0] get doubled-up |
| 78 | if x[0] != x[-1]: |
| 79 | x = np.append(x, x[0]) |
| 80 | y = np.append(y, y[0]) |
| 81 | line.set_data(x, y) |
| 82 | |
| 83 | def set_varlabels(self, labels): |
| 84 | self.set_thetagrids(np.degrees(theta), labels) |
| 85 |
no test coverage detected
searching dependent graphs…