title: How do I add labels to my Radar Chart points in Python Matplotlib
body: <p>Forgive the seemingly simple question.</p>
  
  <p>I've got a radar chart I am using in Power BI that's pulling in data points and changing as I filter data in and out. One problem I am not able to solve is how I add numbers to the chart points. I got most of this code from another post on here, but I cannot seem to figure out how to add those data points. </p>
  
  <p>Please see the picture examples if it doesn't make sense what I am looking for. </p>
  
  <p>Current chart:</p>
  
  <p><img src="https://i.stack.imgur.com/zmaCE.jpg" alt="Current Chart"></p>
  
  <p>Desired chart:</p>
  
  <p><img src="https://i.stack.imgur.com/JO5nl.jpg" alt="Desired Chart"> </p>
  
  <pre class="lang-py prettyprint-override"><code>import numpy as np
  import matplotlib.pyplot as plt
  from matplotlib.patches import Circle, RegularPolygon
  from matplotlib.path import Path
  from matplotlib.projections.polar import PolarAxes
  from matplotlib.projections import register_projection
  from matplotlib.spines import Spine
  from matplotlib.transforms import Affine2D
  
  
  def radar_factory(num_vars, frame='circle'):
      """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.
  
      """
      # calculate evenly-spaced axis angles
      theta = np.linspace(0, 2*np.pi, num_vars, endpoint=False)
  
      class RadarAxes(PolarAxes):
  
          name = 'radar'
  
          def __init__(self, *args, **kwargs):
              super().__init__(*args, **kwargs)
              # rotate plot such that the first axis is at the top
              self.set_theta_zero_location('N')
  
          def fill(self, *args, closed=True, **kwargs):
              """Override fill so that line is closed by default"""
              return super().fill(closed=closed, *args, **kwargs)
  
          def plot(self, *args, **kwargs):
              """Override plot so that line is closed by default"""
              lines = super().plot(19, **kwargs)
              for line in lines:
                  self._close_line(line)
  
          def _close_line(self, line):
              x, y = line.get_data()
              # FIXME: markers at x[0], y[0] get doubled-up
              if x[0] != x[-1]:
                  x = np.concatenate((x, [x[0]]))
                  y = np.concatenate((y, [y[0]]))
                  line.set_data(x, y)
  
          def set_varlabels(self, labels):
              self.set_thetagrids(np.degrees(theta), labels)
  
          def _gen_axes_patch(self):
              # The Axes patch must be centered at (0.5, 0.5) and of radius 0.5
              # in axes coordinates.
              if frame == 'circle':
                  return Circle((0.5, 0.5), 0.5)
              elif frame == 'polygon':
                  return RegularPolygon((0.5, 0.5), num_vars,
                                        radius=0.5, edgecolor="k")
              else:
                  raise ValueError("unknown value for 'frame': %s" % frame)
  
          def draw(self, renderer):
              """ Draw. If frame is polygon, make gridlines polygon-shaped """
              if frame == 'polygon':
                  gridlines = self.yaxis.get_gridlines()
                  for gl in gridlines:
                      gl.get_path()._interpolation_steps = num_vars
              super().draw(renderer)
  
  
          def _gen_axes_spines(self):
              if frame == 'circle':
                  return super()._gen_axes_spines()
              elif frame == 'polygon':
                  # spine_type must be 'left'/'right'/'top'/'bottom'/'circle'.
                  spine = Spine(axes=self,
                                spine_type='circle',
                                path=Path.unit_regular_polygon(num_vars))
                  # unit_regular_polygon gives a polygon of radius 1 centered at
                  # (0, 0) but we want a polygon of radius 0.5 centered at (0.5,
                  # 0.5) in axes coordinates.
                  spine.set_transform(Affine2D().scale(.5).translate(.5, .5)
                                      + self.transAxes)
  
  
                  return {'polar': spine}
              else:
                  raise ValueError("unknown value for 'frame': %s" % frame)
  
      register_projection(RadarAxes)
      return theta
  
  disease_avg = round(dataset["disease_avg"].mean())
  stress_vvg = round(dataset["Stress_Avg"].mean())
  Nutrition_Avg = round(dataset["Nutrition_Avg"].mean())
  Movement_avg = round(dataset["Movement_avg"].mean())
  fitness_avg = round(dataset["fitness_avg"].mean())
  
  
  data = [['Disease Risk', 'Stress', 'Nutrition', 'Movement Quality', 'Fitness'],
          ('Basecase', [[disease_avg, stress_vvg , Nutrition_Avg, Movement_avg, fitness_avg]])]
  
  
  #('Basecase', [[dataset["disease_avg"].mean(), dataset["Stress_Avg"].mean() , dataset["Nutrition_Avg"].mean(),dataset["Movement_avg"].mean(), dataset["fitness_avg"].mean()]])]
  
  cat = ['Disease Risk', 'Stress', 'Nutrition', 'Movement Quality', 'Fitness']
  values = [dataset["disease_avg"].mean(), dataset["Stress_Avg"].mean(), dataset["Nutrition_Avg"].mean(), dataset["Movement_avg"].mean(), dataset["fitness_avg"].mean()]
  
  N = len(data[0])
  theta = radar_factory(N, frame='polygon')
  
  spoke_labels = data.pop(0)
  title, case_data = data[0]
  
  fig, ax = plt.subplots(figsize=(4, 4), subplot_kw=dict(projection='radar'))
  fig.subplots_adjust(wspace=0.25, hspace=0.20, top=0.85, bottom=0.05)
  
  ax.set_rgrids([5, 10, 15, 20])
  #ax.set_title(title,  position=(0.5, 1.1), ha='center')
  
  for d in case_data:
      line = ax.plot(theta, d)
      ax.fill(theta, d,color='#8bbe3f', alpha=0.35)  
  ax.set_varlabels(spoke_labels)
  
  plt.show()
  </code></pre>