Home > Software design >  Equal spacing between pie charts of different sizes in matplotlib
Equal spacing between pie charts of different sizes in matplotlib

Time:12-01

I am having difficulties with setting an equal space between pie charts of different sizes. The 5 are correctly arranged in one row, but the distance between the contours of neighboring pies aren't equal. I tried many abbreviations of the following code, all of them not making a big difference in the output (see image):

#code:

import matplotlib.pyplot as plt
import pandas as pd
labels = 'Verkehr', 'Maschinen und Motoren', 'Feuerungen', 'Industrie / Gewerbe', 'Land- und Forstwirtschaft'
sizesax1 = [108295, 10107, 7220, 11551, 7220]
sizesax2 = [77882, 6676, 6676, 13351, 6676]
sizesax3 = [55652, 4417, 6184, 15900, 6184]
sizesax4 = [36327, 2642, 4632, 16512, 5944]
sizesax5 = [18781, 1409, 3287, 1878, 4695]

fig, (ax1, ax2, ax3, ax4, ax5) = plt.subplots(1, 5, figsize =(20,4))
ax1.pie(sizesax1, startangle=0, colors = ('red', 'darkblue', 'orange', 'yellow', 'green'), radius=1*4)
ax2.pie(sizesax2, startangle=0, colors = ('red', 'darkblue', 'orange', 'yellow', 'green'), radius=.77*4)
ax3.pie(sizesax3, startangle=0, colors = ('red', 'darkblue', 'orange', 'yellow', 'green'), radius=.61*4)
ax4.pie(sizesax4, startangle=0, colors = ('red', 'darkblue', 'orange', 'yellow', 'green'), radius=.46*4)
ax5.pie(sizesax5, startangle=0, colors = ('red', 'darkblue', 'orange', 'yellow', 'green'), radius=.33*4)

some additions i tried:

fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=1, hspace=None)

or

fig.tight_layout()
#giving me this error message:
/srv/conda/envs/notebook/lib/python3.7/site-packages/ipykernel_launcher.py:17: UserWarning:
Tight layout not applied. The bottom and top margins cannot be made large enough to
accommodate all axes decorations.

and some others.

Big thank you already for reading this! I am a complete beginner in python and just managed to come as far as you see in this image:

enter image description here

CodePudding user response:

It is not clear what it is required. I'll assume it is the following image:

enter image description here

Fundamentally, the problem is that the pie needs a square aspect ratio, which is not provided by a row of subplots.

The simplest solution, is to create only one plot and plot there multiple pies with different centres. Something like:

import matplotlib.pyplot as plt

sizes = [ [108295, 10107, 7220, 11551, 7220],
          [77882, 6676, 6676, 13351, 6676],
          [55652, 4417, 6184, 15900, 6184],
          [36327, 2642, 4632, 16512, 5944],
          [18781, 1409, 3287, 1878, 4695]]

colors = ('red', 'darkblue', 'orange', 'yellow', 'green')

R = 4

radius = [R*i for i in [1.0, 0.77, 0.61, 0.46, 0.33] ]
wid = sum(radius)*2
hei = R*2

fig, ax = plt.subplots(figsize =(wid,hei))
fig.subplots_adjust(left = 0, right = 1, bottom = 0, top = 1)

y = R
x = 0

for i in range(5):

    x  = radius[i]
    ax.pie(sizes[i], startangle = 0, colors = colors,
           radius = radius[i], center = (x,y) )
    x  = radius[i]

ax.set(xlim =(0,x), ylim=(0,R*2))

plt.savefig("aaa.png")

Notice that my figure aspect ratio is not the (20,4) of the question, which does not hold for the way I interpreted the intended result.

But it might be the case that there is the need of having these in different axes. If so, the idea is:

  1. Use gridspec to create a single row with 5 columns and provide the ratios so that they correspond to the required radius.

  2. Plot the larger pie in the left slot.

  3. In all remaining slots, use a subgrid, dividing into a column of three (sub-)slots.

  4. Set the height ratios so that the middle one ends up with an aspect ratio of a square.

  5. Plot the pies in the middle slots.

Here we go:

import matplotlib.pyplot as plt


sizes = [ [108295, 10107, 7220, 11551, 7220],
          [77882, 6676, 6676, 13351, 6676],
          [55652, 4417, 6184, 15900, 6184],
          [36327, 2642, 4632, 16512, 5944],
          [18781, 1409, 3287, 1878, 4695]]

colors = ('red', 'darkblue', 'orange', 'yellow', 'green')

R = 4

radius = [R*i for i in [1.0, 0.77, 0.61, 0.46, 0.33] ]
wid = sum(radius)*2
hei = R*2
ratios = [i/radius[0] for i in radius] # for gridspec

fig = plt.figure(figsize =(wid,hei))
gs = fig.add_gridspec(1, 5,
                      width_ratios = ratios,
                      wspace=0, left = 0, right = 1, bottom = 0, top = 1)

ax = fig.add_subplot(gs[0,0])
ax.pie(sizes[0], startangle = 0, colors = colors, radius = 1 )
ax.set(xlim=(-1,1) ,ylim=(-1,1))
    
for i in range(1,5):

    mid = ratios[i]/sum(ratios)*wid
    inrat = [(hei-mid)/2, mid, (hei-mid)/2]
    ings = gs[0,i].subgridspec(3, 1, hspace=0,
                               height_ratios = inrat)
    
    ax = fig.add_subplot(ings[1,0])
    ax.pie(sizes[i], startangle = 0, colors = colors, radius = 1 )
    ax.set(xlim=(-1,1), ylim=(-1,1))

plt.savefig("aaa.png")
  • Related