Home > Back-end >  Adjust text positions and remove some part of the pie chart in matplotlib python
Adjust text positions and remove some part of the pie chart in matplotlib python

Time:03-11

I try to produce a nested pie chart as an example below. However, the text position looks not as beautiful as it should be. I want to adjust the text positions in the inner pie chart as fit inside the pie part (best along in red line, but if it is inside and looks good just okay). Also, I want to remove one part of pie chart as outline in the picture below. Any help would be very helpful.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt    
data=pd.read_csv(r"https://raw.githubusercontent.com/tuyenhavan/Course_Data/main/test_pie_chart.csv")
# Get outer and inner counts
inner=data.groupby(["Col1"]).size()
outer=data.groupby(["Col1","Col2"]).size()
# Get outer and inner labels
inner_label=[f"{idx} ({val/sum(inner.values.flatten())*100:.2f}%)" for idx, val in zip(inner.index.get_level_values(0),inner.values.flatten())]
outer_label=[f"{idx} ({val/sum(outer.values.flatten())*100:.2f}%)" for idx, val in zip(outer.index.get_level_values(1), outer.values.flatten())]
# Inner and outer colors
inner_color=["#16A085","#808000","#BA4A00"]
outer_color=["#808080","#229954","#34495E","#2E86C1","#CA6F1E","white","#808080","#229954","#CA6F1E","#00FFFF"]
# Set figure size and radius adjustment
fig, ax=plt.subplots(figsize=(10,8))
size=0.4
# Plot the inner pie chart
ax.pie(inner.values.flatten(), labels=inner_label, radius=1-size,wedgeprops=dict(width=size, edgecolor='w'),\
      colors=inner_color,textprops ={"fontsize":12},labeldistance=0.4) # labels=inner_label,autopct ='%1.1f%%', 
# Plot the outer pie chart
ax.pie(outer.values.flatten(), radius=1, labels=outer_label,wedgeprops=dict(width=size, edgecolor='w'),\
      colors=outer_color, textprops={"fontsize":12},labeldistance=1.1)
ax.set(xlim=(-1,1), ylim=(-1,1))
ax.set(aspect="equal")
plt.show()

enter image description here

CodePudding user response:

To achieve what You want, You have to play a bit with text labels. You can position each individual wedge and label. List of wedges and labels are returned from ax.pie() method.

To remove label, just set its text to empty string.

To have nicer inner labels, I would suggest to move percentage to new line and then rotate each label accordingly.

Here is code snippet doing so:

import matplotlib.pyplot as plt
import pandas as pd

data = pd.read_csv(r"https://raw.githubusercontent.com/tuyenhavan/Course_Data/main/test_pie_chart.csv")
# Get outer and inner counts
inner = data.groupby(["Col1"]).size()
outer = data.groupby(["Col1", "Col2"]).size()
# Get outer and inner labels
inner_label = [f"{idx} \n({val / sum(inner.values.flatten()) * 100:.2f}%)" for idx, val in
               zip(inner.index.get_level_values(0), inner.values.flatten())]
outer_label = [f"{idx} ({val / sum(outer.values.flatten()) * 100:.2f}%)" for idx, val in
               zip(outer.index.get_level_values(1), outer.values.flatten())]
# Inner and outer colors
inner_color = ["#16A085", "#808000", "#BA4A00"]
outer_color = ["#808080", "#229954", "#34495E", "#2E86C1", "#CA6F1E", "white", "#808080", "#229954", "#CA6F1E",
               "#00FFFF"]
# Set figure size and radius adjustment
fig, ax = plt.subplots(figsize=(10, 8))
size = 0.4
# Plot the inner pie chart
wedges_lst, labels_lst = ax.pie(inner.values.flatten(), labels=inner_label, radius=1 - size, wedgeprops=dict(width=size, edgecolor='w'), \
       colors=inner_color, textprops={"fontsize": 12}, labeldistance=0.6)  # labels=inner_label,autopct ='%1.1f%%',
labels_lst[0].update({"rotation": 0, "horizontalalignment": "center", "verticalalignment": "center"})
labels_lst[1].update({"rotation": 135, "horizontalalignment": "center", "verticalalignment": "center"})
labels_lst[2].update({"rotation": 225, "horizontalalignment": "center", "verticalalignment": "center"})

# Plot the outer pie chart
wedges_lst, labels_lst = ax.pie(outer.values.flatten(), radius=1, labels=outer_label, wedgeprops=dict(width=size, edgecolor='w'), \
       colors=outer_color, textprops={"fontsize": 12}, labeldistance=1.1)

# Remove # No text label
labels_lst[5].update({"text": ""})

ax.set(xlim=(-1, 1), ylim=(-1, 1))
ax.set(aspect="equal")
plt.show()

Resulting in: Pie Chart

  • Related