Search code examples
pythonpython-3.xmatplotlibpie-chart

Drawing multiple donut charts


I am writing a code to output 3 donut charts. I draw 3 pie charts at first, and then I want to fill each one with a white circle.

I am successfully outputting 3 pie charts, but the white circle appears only on the last one.

How do I make it appear on all three?

fig, axes = plt.subplots(1,3, figsize=(10,5))
for ax, col in zip(axes, df.columns):
    ax.pie(df[col], labels=None,  colors=colors)
    ax.set(ylabel='', title=col, aspect='equal')
    centre_circle = plt.Circle((0,0),0.70,fc='white')
    fig = plt.gcf()
    fig.gca().add_artist(centre_circle)

axes[0].legend(labels, bbox_to_anchor=(0, 0.5))



fig.savefig('your_file.png')
plt.show()

Sample output


Solution

  • Because fig.gca() holds the last created axis in the figure, so the white circle is placed there three times independently of the loop variables.
    You can simply add the circle artist to the axis in each iteration by using your ax variable

    ax.add_artist(centre_circle)
    

    However, your approch seems to be an unnecessary workaround for me, because you can accomplish the donut shape by using the wedgeprops kwarg with its width parameter (see here for further ones):

    try e.g.

    ax.pie(df[col], labels=None, colors=colors, wedgeprops=dict(width=.3))
    

    instead of painting the white circle manually after each pie creation.


    full example:

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    
    np.random.seed(42)
    df = pd.DataFrame(np.random.randint(5, 10, (7, 3)), columns=['a', 'b', 'c'])
    
    fig, axes = plt.subplots(1,3, figsize=(10,5))
    for ax, col in zip(axes, df.columns):
        ax.pie(df[col], wedgeprops=dict(width=.3))
        ax.set(ylabel='', title=col, aspect='equal')
    

    enter image description here


    Note that you even do not have to loop over your columns but could create a pie chart directly from the pandas dataframe:

    df.plot(kind='pie', subplots=True, wedgeprops=dict(width=.3), legend=False, labels=None)
    

    result:

    enter image description here