Page 13 sur 26
Pie Chart
Simple pie
If you have a data-frame with fields Categories and Total, you can create a pie chart.
import matplotlib.pyplot as plt chartLabel = df_Categories_count['Categories'].tolist() chartValue = df_Categories_count['Total'].tolist() colors = plt.rcParams['axes.prop_cycle'].by_key()['color'] fig1 = plt.figure() plt.pie(chartValue, labels=chartLabel, colors=colors, autopct=None, shadow=False, startangle=90) plt.axis('equal') plt.title('Categories', pad=20, fontsize=15) plt.show() plt.clf()
Display percentages in the chart
Use autopct
.
plt.pie(chartValue, labels=chartLabel, colors=colors, autopct='%1.1f%%', shadow=False, startangle=90)
Change the labels font size
plt.rcParams['font.size'] = 5
Hide a label in chart
Just replace the value with an empty string.
chartLabel[-1] = ''
Add a legend in your chart
plt.legend(chartLabel, loc='best', fontsize=8)
Explode
To explode your chart, you need to pass values in explode
, example if you have 4 values to plot:
plt.pie(myValue, labels=myLabels, colors=colors, explode=[0.05, 0.05, 0.05, 0.05], autopct=None, shadow=False, startangle=90)
If you want explode all part by default, just create a list before:
explodeValues = [] for i in myValue: explodeValues.append(0.05) plt.pie(myValue, labels=myLabels, colors=colors, explode=explodeValues, autopct=None, shadow=False, startangle=90)
Add a legend with several fields
For example you want display labels and percentages in the legend. First calculate percentages in another field in your data-frame, then:
import matplotlib.pyplot as plt chartLabel = df_Categories_count['Categories'].tolist() chartLegendLabel = df_Categories_count['Categories'].tolist() chartValue = df_Categories_count['Total'].tolist() chartLegendPercent = df_Categories_count['Percent'].tolist() legendLabels = [] for i, j in zip(chartLegendLabel, map(str, chartLegendPercent)): legendLabels.append(i + ' (' + j + ' %)') colors = plt.rcParams['axes.prop_cycle'].by_key()['color'] fig1 = plt.figure() plt.pie(chartValue, labels=chartLabel, colors=colors, autopct=None, shadow=False, startangle=90) plt.axis('equal') plt.title('Categories', pad=20, fontsize=15) plt.legend(legendLabels, loc='best', fontsize=8) plt.show() plt.clf()
Display only first labels around the plot
... # Display only first indices in legend def autopct_masque(index_mask): def format_pct(pct, allvals): index = format_pct.index format_pct.index += 1 if index in index_mask: return '' # Masquer ce pourcentage return f'{pct:.1f}%' format_pct.index = 0 return lambda pct: format_pct(pct, chartLegendPercent) ... # Create plot # Sort a DF previously calculating percentage df_sorted = myDf.sort_values(by='Pourcentage', ascending=False).reset_index(drop=True) chartLabel = df_sorted['fieldPreviouslyGroupedForPercentage'].tolist() chartLegendLabel = df_sorted['fieldPreviouslyGroupedForPercentage'].tolist() chartValue = df_sorted['Total'].tolist() chartLegendPercent = df_sorted['Pourcentage'].tolist() # Display only first indices displayOnlyFirst = 4 calculHowManyToHide = len(chartLegendPercent) - displayOnlyFirst hiddenIndices = list(range(len(chartLegendPercent) - calculHowManyToHide, len(chartLegendPercent))) # Hide last indices for i in hiddenIndices: chartLabel[i] = '' explodeValues = [0.05] * len(chartValue) legendLabels = [] for i, j in zip(chartLegendLabel, map(str, chartLegendPercent)): legendLabels.append(i + ' (' + j + ' %)') # Colors colors = plt.rcParams['axes.prop_cycle'].by_key()['color'] myFig = plt.figure() # Get objects to hide indices and format plot wedges, texts, autotexts = plt.pie( chartValue, labels=chartLabel, colors=colors, explode=explodeValues, autopct=autopct_masque(hiddenIndices), shadow=False, startangle=90, labeldistance=1 ) ...
Customize text labels around the plot
# Customize labels around the plot wordToDelete = 'Specialty' for text in texts: ancien_texte = text.get_text() nouveau_texte = ancien_texte.replace(wordToDelete, '').strip() text.set_text(nouveau_texte) for i, text in enumerate(texts): label = chartLabel[i] if label == 'Value1... blablabla': # text.set_color('blue') text.set_fontsize(9) # text.set_fontweight('bold') text.set_text('Value1\nblablabla') elif label == 'Value2... blablabla': text.set_text('Value2\nblablabla\nblablabla') text.set_fontsize(9) elif label == 'Value3... blablabla': text.set_text('Value3\nblablabla\nblablabla') text.set_fontsize(9) else: text.set_fontsize(9) # Reduce percentage size font for autotext in autotexts: autotext.set_fontsize(8) plt.axis('equal') plt.title('EDS Terminale 2', pad=20, fontsize=15) myFig.savefig(downloadsDir+'myPlot.png', dpi=100) plt.clf() im = Image.open(downloadsDir+'myPlot.png') bordered = ImageOps.expand(im, border=1, fill=(0, 0, 0)) bordered.save(downloadsDir+'myPlot.png') # Insert in Excel img = openpyxl.drawing.image.Image(downloadsDir+'myPlot.png') img.anchor = 'E4' workbook['An Excel tab'].add_image(img) workbook.save(statsFile) ... os.remove(downloadsDir + 'myPlot.png')