Sunday 21 July 2024

Web Tutorial: Python Matplotlib Pie Chart

Howdy, folks!

Now that we're on a roll with the Python matplotlib bar and line charts, we should absolutely go ahead and make a pie chart. This one is going to be simple because most of the work - data gathering and massaging - has already been done with the bar chart. And with matplotlib, the tough calculations are taken care of! Therefore, this web tutorial will not be a two-parter.

Just take the code for the bar chart here, and begin by clearing out the contents of the barChart() function. Then rename the function to pieChart(). Also, we won't be using numpy, so remove the line that imports that library.
#import numpy as np
import matplotlib.pyplot as plt

def pieChart(labels, vals, season, stat):


Also, change the call to the function. With these small changes done, we're all set to create a pie chart!
stats = [];
for v in values:
  stats.append(v[stat])

pieChart(players, stats, season, stat)


We begin by using the figure() method to set the size of the chart. For this, I recommend a square value, meaning the width is the same as the height.
def pieChart(labels, vals, season, stat):
  plt.figure(figsize = (8, 8))


We then use the pie() method. In it, we pass vals, then pass labels as the labels argument.
def pieChart(labels, vals, season, stat):
  plt.figure(figsize = (8, 8))
  
  plt.pie(vals, labels=labels)


We then use the title() method to display the stat type and season. You'll notice that we still use the custom function seasonName() that we created for the bar chart.
def pieChart(labels, vals, season, stat):
  plt.figure(figsize = (8, 8))
  
  plt.pie(vals, labels=labels)

  plt.title("Liverpool FC Player " + stat + " for " + seasonName(season))


Finally, of course, we use the show() method to display the chart.
def pieChart(labels, vals, season, stat):
  plt.figure(figsize = (8, 8))
  
  plt.pie(vals, labels=labels)

  plt.title("Liverpool FC Player " + stat + " for " + seasonName(season))
  plt.show()


Now we run the program. I select the 2021/2022 season and select appearances as the stat type. We get a colorful pie chart!


Here's something potentially useful - a legend!
def pieChart(labels, vals, season, stat):
  plt.figure(figsize = (8, 8))
  
  #customcolors = [];
  #customexplode = [];

  plt.pie(vals, labels=labels)
  plt.legend()

  plt.title("Liverpool FC Player " + stat + " for " + seasonName(season))
  plt.show()


This is for when you have a lot of colors, and you want an easy way to refer without having to squint at the labels.


However, we're not going to use it because I have something else entirely in mind. So, remove this line.
def pieChart(labels, vals, season, stat):
  plt.figure(figsize = (8, 8))

  plt.pie(vals, labels=labels)
  #plt.legend()

  plt.title("Liverpool FC Player " + stat + " for " + seasonName(season))
  plt.show()


Let's put percentages into the wedges. The autopct argument is how we format the string to display percentage labels.
plt.pie(vals, labels=labels, autopct="%1.1f%%")


Neat!


Next up, let me show you why I didn't want the legend earlier. That's because, this being a Liverpool FC chart, I want it in shades of red. And if everything's a shade of red, the legend is going to be next to useless. Start by declaring the list, customcolors. Follow up with a For loop that iterates through vals. Since we want the index value, use enumerate() on vals.
def pieChart(labels, vals, season, stat):
  plt.figure(figsize = (8, 8))
  
  customcolors = [];

  for index, value in enumerate(vals):
      
  plt.pie(vals, labels=labels, autopct="%1.1f%%")

  plt.title("Liverpool FC Player " + stat + " for " + seasonName(season))
  plt.show()


For each element, append stuff in customcolors. We want a Hex string that represents the a shade of the color red. So the string is going to be "#" followed by 6 characters. The last 4 are always "0000".
def pieChart(labels, vals, season, stat):
  plt.figure(figsize = (8, 8))
  
  customcolors = [];

  for index, value in enumerate(vals):
    customcolors.append("#" + + "0000")
      
  plt.pie(vals, labels=labels, autopct="%1.1f%%")

  plt.title("Liverpool FC Player " + stat + " for " + seasonName(season))
  plt.show()


And as for the missing 2 characters, we want them to be any Hex value from "96" up to "FF". So, use index with a formula that gets progressively bigger with each iteration. The lowest possible number is 150 (which is 96 in Hexadecimal). To ensure that it's always a two-character Hex value, run the result in the format() function, passing in "02x" as the second argument.
def pieChart(labels, vals, season, stat):
  plt.figure(figsize = (8, 8))
  
  customcolors = [];

  for index, value in enumerate(vals):
    customcolors.append("#" + format(index * 20 + 150, "02x") + "0000")
      
  plt.pie(vals, labels=labels, autopct="%1.1f%%")

  plt.title("Liverpool FC Player " + stat + " for " + seasonName(season))
  plt.show()


At the end of this, customcolors should be a list full of Hex values of the color red! Add it to the pie() function as the argument colors.
plt.pie(vals, labels=labels, colors=customcolors, autopct="%1.1f%%")


I've deliberately selected a season with a lot of values to let you see what it looks like. The colors are disparate enough that they look distinct when right next to each other, but again, useless as part of a legend. Also, be warned, this is not going to work if you have more than a handful of values!


The next thing you might want to do is cut out a wedge of that pie. Let's say we want the biggest contributor to the pie to stand out further. What do we do? Why, we pass in a list with float values that will tell Python how much we want each wedge to be separated from the rest - not at all (a 0) or a little (any value greater than 0 but less than 1). To do that, we need another list, customexplode.
def pieChart(labels, vals, season, stat):
  plt.figure(figsize = (8, 8))
  
  customcolors = [];
  customexplode = [];

  for index, value in enumerate(vals):
    customcolors.append("#" + format(index * 20 + 150, "02x") + "0000")
      
  plt.pie(vals, labels=labels, colors=customcolors, autopct="%1.1f%%")

  plt.title("Liverpool FC Player " + stat + " for " + seasonName(season))
  plt.show()


In the For loop, check if value is equal to the highest possible value in vals. If so, add 0.1 to the list. If not, add 0 to the list.
for index, value in enumerate(vals):
  customcolors.append("#" + format(index * 20 + 150, "02x") + "0000")
  
  if (value == max(vals)):
    customexplode.append(0.1)
  else:
    customexplode.append(0)


Then put customexplode into the pie() function as the argument explode.
for index, value in enumerate(vals):
  customcolors.append("#" + format(index * 20 + 150, "02x") + "0000")
  
  if (value == max(vals)):
    customexplode.append(0.1)
  else:
    customexplode.append(0)
    
plt.pie(vals, labels=labels, colors=customcolors, explode=customexplode, autopct="%1.1f%%"")


And this is what happens!



That was short and sweet...

As mentioned at the start, most of the work had already been done in previous web tutorials. The only thing left was really to use the data to render the pie chart.

Goodpie for now,
T___T

No comments:

Post a Comment