Reputation: 31
I'm making a series of pie charts, and I'm looking for a way to automatically place the legend to avoid overlapping other elements (not just a manual intervention for each individual plot). For example:
fake_df = pd.DataFrame([70, 15, 15],
columns=['category'],
index=['Category Name 1', 'Category Name 2', 'Category Name 3'])
fake_df.plot.pie(y='category',
labels=None,
autopct="%1.0f%%",
pctdistance=1.2,
)
I know that in this individual case I can explicitly assign the legend to 'upper left', or manually manipulate the placement of the legend or percentages in other ways to avoid the overlap, but that doesn't work for cases where the percentages show up in the upper left for example:
fake_df = pd.DataFrame([71, 15, 14],
columns=['category'],
index=['Category Name 1', 'Category Name 2', 'Category Name 3'])
fake_df.plot.pie(y='category',
labels=None,
autopct="%1.0f%%",
pctdistance=1.2,
)
plt.legend(['Category Name 1', 'Category Name 2', 'Category Name 3'], loc='upper left')
And since I'm automatically making a large amount of pie charts where there isn't a single legend placement that will always work and I can't know where the potential overlaps will be, I want a general solution that reliably places the legend such that it avoids the overlap. Is this possible?
Upvotes: 0
Views: 2218
Reputation: 925
fake_df = pd.DataFrame([70, 15, 15],
columns=['category'],
index=['Category Name 1', 'Category Name 2', 'Category Name 3'])
ax = fake_df.plot.pie(y='category',
labels=None,
autopct="%1.0f%%",
pctdistance=1.2,
)
plt.legend(labels=fake_df.index, bbox_to_anchor=(1.05, 1), loc='upper left')
EDIT AFTER YOU HAVE UPDATED YOUR ANSWER WITH PARTIAL OF THE ABOVE CODE:
You also need to use bbox_to_anchor parameter so that the legends placement does not overlap with the plot.
bbox_to_anchor : parameter tells matplotlib how to position the legend relative to the anchor point (bbox_to_anchor argument allows arbitrary placement of the legend).
loc : parameter tells matplotlib which corner of the legend should align with the anchor point
If you don't specify the loc
argument it will take the default value of "best" which makes matplotlib determine the location itself. By assigning the value of "upper left" to that parameter you are telling matplotlib which corner of the legend box should align with the anchor point.
From documents https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.legend.html
Upvotes: 1
Reputation: 977
You could probably place each pandas pie chart in a matplotlib figure, setting the legend
argument of the chart to None
, while creating a figure legend like this:
import matplotlib.pyplot as plt
import pandas as pd
fig = plt.figure()
ax = fig.add_subplot()
fake_df = pd.DataFrame([71, 15, 14],
columns=['category'],
index=['Category Name 1', 'Category Name 2', 'Category Name 3'])
fake_df.plot.pie(y='category',
labels=None,
legend=None,
autopct="%1.0f%%",
pctdistance=1.2,
ax=ax
)
fig.legend(labels=fake_df.index)
plt.show()
The result:
Upvotes: 1