Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pandas pie charts subplots labels overlap with slice labels

Similarly to this question, I am using the subplots keyword in matplotlib except I am drawing pie charts and using pandas.

The labels on my subplots crash with the slice labels when the labels are close to horizontal:

first = pd.Series({'True':2316, 'False': 64})
second = pd.Series({'True':2351, 'False': 29})
df = pd.concat([first, second], axis=1, keys=['First pie', 'Second pie'])
axes = df.plot(kind='pie', subplots=True)
for ax in axes:
    ax.set_aspect('equal')

First pie example

I can alleviate this somewhat by doing as the docs do and adding an explicit figsize, but it still looks pretty cramped:

axes = df.plot(kind='pie', figsize=[10, 4], subplots=True)
for ax in axes:
    ax.set_aspect('equal')

Second pie example

Is there a nice way to do better. Something to do with tight_layout maybe?

like image 783
LondonRob Avatar asked Dec 23 '22 13:12

LondonRob


1 Answers

You can move the label to the left using ax.yaxis.set_label_coords(), and then adjust the coords to a value that suits you.

The two inputs to set_label_coords are the x and y coordinate of the label, in Axes fraction coordinates.

For your plot, I found (-0.15, 0.5) to work well (i.e. x=-0.15 means 15% of the axes width to the left of the axes, and y=0.5 means half way up the axes). In general then, assuming you always want the label to be centered on the y axis, you only need to adjust the x coordinate.

I also added some space between the plots using subplots_adjust(wspace=0.5) so that the axes label didn't then overlap with the False label from the other pie.

import pandas as pd
import matplotlib.pyplot as plt

first = pd.Series({'True':2316, 'False': 64})
second = pd.Series({'True':2351, 'False': 29})
df = pd.concat([first, second], axis=1, keys=['First pie', 'Second pie'])
axes = df.plot(kind='pie', subplots=True)
for ax in axes:
    ax.set_aspect('equal')
    ax.yaxis.set_label_coords(-0.15, 0.5)

plt.subplots_adjust(wspace=0.5)

plt.show()

enter image description here

like image 175
tmdavison Avatar answered Feb 16 '23 00:02

tmdavison