Code snippets are bits of re-usable code submitted by the ReportLab community. We don't promise that they are accurate, up-to-date or correct - use them at your own risk!

We'd love it if you could participate by submitting your own snippets and sharing your experience with others by commenting. You will need to create a user account by filling out our very simple form.

View all snippets

Side Labelled Pie Chart

31 Aug 2012
opensource rl-toolkit

Labelling pie charts is always difficult. If the data is dynamic, you will often end up with many labels crowded closely together, often in places a human designer wouldn't put them. The 'safe' approach has traditionally been to have a separate legend, and no text around the pie.

We have attempted to implement a semi-intelligent labelling system which appears to work in most cases. If the new 'sideLabels' attribute is set to true, then the labels of the slices are placed in two columns, one on either side of the pie. The start angle of the pie will be automatically chosen to try to get most of the slices "near the sides" rather than "near the top and bottom", to space the lines out.

You are still advised to preprocess your data so that the number of slices is limited - for example, grouping any slices less than 1-2% of the data into an 'other' category - as there is always a limit to how much text can stack up in a finite space.

The distance from the edge of the pie from the edge of either column is decided by the sideLabelsOffset attribute, which is a fraction of the width of the pie.

If xradius is changed, the pie can overlap the labels, and so we advise leaving xradius as None. If you have sideLabels set to True, then some of the attributes become redundant, such as pointerLabelMode. Also sideLabelsOffset only changes the label position if sideLabels is set to true.

from import Pie
from import Drawing, _DrawingEditorMixin
from reportlab.lib.colors import Color, magenta, cyan

class pietests(_DrawingEditorMixin,Drawing):
    def __init__(self,width=400,height=200,*args,**kw):
        self.pie.sideLabels       = 1
        self.pie.labels           = ['Label 1', 'Label 2', 'Label 3', 'Label 4', 'Label 5']             = [20, 10, 5, 5, 5]
        self.pie.width            = 140
        self.pie.height           = 140
        self.pie.y                = 35
        self.pie.x                = 125