0

I saw a certain Chart Type whose visualization of data I really like. Sadly I don't know the name of it to look up a tutorial. Screenshot

I have some data which would perfectly fit this chart type (imo). However I would need some help to create this. I have some basic Python knowledge and did some plotting before but nothing like this.

This is the data I'd like to visualize

countries = ["Bolivien","Argentinien","US","Chile","Australien","China","Deutschland","DR" "Kongo","Kanada","Mexiko","Tschechien","Serbien","Weitere"]
resources = [21,20,12,11,7.9,6.8,3.2,3,2.9,1.7,1.3,1.2,6]
percentages = [21.43,20.41,12.24,11.22,8.06,6.94,3.27,3.06,2.96,1.73,1.33,1.22,6.12]

The countries should be the x-axis values. The bars should be the height of the percentages with the y-axis totalling up to 100% as in the example picture. The different bars should have the resources values as labels. There does not need to be a colorscheme applied to the bars.

How would someone go about creating this?

Any help is greatly appreciated! Thanks

  • Try looking at seaborn. This might be similar to what you are trying to find. https://seaborn.pydata.org/examples/multiple_ecdf.html – trent Mar 01 '23 at 13:15
  • Also, check out waterfall chart [here](https://www.machinelearningplus.com/waterfall-plot-in-python/) and [here](https://plotly.com/python/waterfall-charts/) – Redox Mar 01 '23 at 13:27
  • Wow! First Trent: sadly not what I needed but some beautiful stuff there will definetly get used at some point. Second Redox: Yep it was a waterfall after all. I thought waterfalls are there to visualize positive and negative values at once. A bit silly. You can reply with an answer so I can upvote :) – simon.moebs Mar 01 '23 at 13:38
  • Does this help? https://stackoverflow.com/questions/38222453/how-do-i-create-a-bar-chart-that-starts-and-ends-in-a-certain-range – sbottingota Mar 01 '23 at 13:41

1 Answers1

1

My attempt to do this, as I did not read the comment where it was mentioned that this is a waterfall chart in time.

My initial idea was to create a patch for each possible value, and have a variable, sum_percentage, that tracks the value where each rectangle should start. This forces to define the limits for the x and y axis manually, otherwise they are not updated.

The result: enter image description here

and the code:

import matplotlib
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import numpy as np

countries = ["Bolivien","Argentinien","US","Chile","Australien","China","Deutschland","DR" "Kongo","Kanada","Mexiko","Tschechien","Serbien","Weitere"]
resources = [21,20,12,11,7.9,6.8,3.2,3,2.9,1.7,1.3,1.2,6]
percentages = [21.43,20.41,12.24,11.22,8.06,6.94,3.27,3.06,2.96,1.73,1.33,1.22,6.12]

square_width = 1 # Sets width in x axis 
center_x = np.arange(0.5,12.6,1) # center of each bar, employed for the x-ticks

# Facecolors
colors = plt.cm.spring(np.linspace(0,1,len(countries)))

sum_percent = 0 # Tracks current added value of percentages
fig, ax = plt.subplots(1, 1)
for ii in range(len(countries)): # For each country
    # Create and add corresponding patch
    left, bottom, width, height = (center_x[ii]-square_width/2, 
                                   sum_percent, 
                                   square_width, 
                                   percentages[ii])
    rect = plt.Rectangle((left, bottom), width, height,
                     facecolor=colors[ii], alpha=0.5)
    ax.add_patch(rect)
    # Create and add text in center of patches
    ax.text(center_x[ii], sum_percent + percentages[ii]/2,str(resources[ii]), va = 'center', ha = 'center')
    # Update sum_percent
    sum_percent = sum_percent + percentages[ii]  
plt.xticks(center_x, countries, rotation = 45)
plt.ylabel('Percentage (%)')
plt.ylim([0 ,100]) # Because patches does not change the y limits
plt.xlim([0, len(countries)])
plt.tight_layout()
plt.show()

EDIT: If you want to have everything update if you change the list of countries, the following:

center_x = np.arange(0.5,12.6,1) # center of each bar, employed for the x-ticks

should be updated to something like this:

center_x = np.arange(square_width/2, len(countries)-square_width/2+0.1, square_width) # center of each bar, employed for the x-ticks
Jes
  • 130
  • 4