Albus Dumbledore's Screen Time

Who do you think has the most screen time among the Harry Potter movies?

Let’s ignore Harry, Hermione and Ron. Who’s next? Dumbledore? Voldemort? Someone else? Explore the video below for the answer.

This is a bar chart race. This tutorial explains how to create it.

Here’s a video explaining each step of this tutorial.

Create the data

Let’s start with the data. The original dataset has every Harry Potter character’s Screen Time. We can take a simpler dataset that has the top 5 characters (by screen time) in each movie.

Sample data

Each row has the screen time for a character in a movie – ignoring Harry, Hermione and Ron.

Create the source template

We’ll create a template where each slide has 1 movie, and we’ll show the characters as a bar chart, like this:

Target slide

Start by creating a template.pptx like this:

Initial template

The relevant shapes are:

Create the rules

Let’s set up a basic gramex.yaml file that loads the template and the data.

url:
  pptxhandler/albus-dumbledore:
    pattern: /$YAMLURL/output.pptx
    handler: PPTXHandler
    kwargs:
      version: 2
      source: template.pptx
      data:
        url: screen-time.xlsx

At this point (and any other time), you can run slidesense on the command line to see the output PPTX. Right now the output is exactly the same as template.pptx.

Next, we create a rule to copy one slide for each movie using copy-slide. It loops through each row in the dataset data

rules:
  - copy-slide: data.groupby('Movie', sort=False)
    transition:
      type: f'morph'
      duration: 1

data.groupby('Movie', sort=False) groups by movie. This ensures that we have one slide per movie (without sorting alphabetically).

We also apply a 1-second morph transition for the bars to animate smoothly into each other.

Next, we set the title of the slide to be the movie name.

Title:
  text: "copy.key"

copy.key has the index of data. Since we grouped by movie, copy.key is the same as the movie.

Now, the output will have one slide for each of the movies. The slide title is updated.

Output has one slide per movie

Next, copy each character name – once for each character.

Name:
  clone-shape: copy.val
  add-top: 1.2 * clone.pos
  name: f"!!{clone.val['Character']} name"
  text: clone.val['Character']

Here, copy.val has one row for each movie. This is what it looks like:

copy.val structure

Next, we set the widths of the bars.

Bar:
  clone-shape: copy.val
  add-top: 1.2 * clone.pos
  name: f"!!{clone.val['Character']} bar"
  width: 5 * clone.val['Minutes'] / clone.val['Max Minutes']
  text: f"{clone.val['Minutes']:.0f} min"
  fill: "'ACCENT_2' if clone.val['Character'] == 'Albus Dumbledore' else 'ACCENT_4'"

These three are practically identical to what we did with the name.

This is the final configuration

See the result

This creates these 9 slides, with transitions:

Bar chart race output

These slides were exactly the ones used to create this video: