publiplots.pieplot#
- publiplots.pieplot(data, x, y=None, hue=None, *, ax=None, donut=0.0, start_angle=90.0, direction='clockwise', order=None, hue_order=None, sort=False, pull=None, gap=None, min_share=0.0, center_label=None, aspect='cell', palette=None, hatch=None, hatch_map=None, hatch_order=None, color=None, edgecolor=None, linewidth=None, alpha=None, legend=True, legend_kws=None, annotate=None, title='', **kwargs)[source]#
Draw a pie or donut chart.
A pie is the one-level case of a nested part-of-whole chart.
xnames the category column,ythe value (omitted, rows are counted), andhuewhat determines colour – defaulting toxitself, which is what every pie does. Only one level is supported: the machinery underneath is written for a tree, but this function draws a single ring.- Parameters:
data (pandas.DataFrame) – Tidy input. One row per observation, or one row per category when pre-aggregated.
x (str) – Column naming each wedge. A sequence of length 1 is accepted; anything longer raises, because only one ring is drawn. Rows whose
xisNaNare dropped and the remaining wedges renormalise to fill the circle, silently – a pie cannot show a missing category, so drop or fill them yourself if the share they represent matters.y (str, optional) – Value column, summed within each category. When omitted, rows are counted.
hue (str, optional) – Column determining colour. Defaults to
x. A categorical hue must be constant within a wedge.ax (Axes, optional) – Matplotlib axes to draw on. If
None, creates a new figure viapubliplots.layout.subplots()so the publiplots layout manager can keep geometry stable. To control axes dimensions, pre-create withpp.subplots(axes_size=(w_mm, h_mm))and passax=.donut (float, default 0.0) – Inner radius as a fraction of the outer radius.
0.5leaves a hole of half the radius, which is wherecenter_labelgoes.start_angle (float, default 90.0) – Angle of the first wedge’s leading edge, in degrees. 90 is twelve o’clock.
direction ({'clockwise', 'counterclockwise'}, default 'clockwise')
order (sequence, optional) – Explicit wedge order. Categories absent from the data are dropped; categories absent from
orderare filtered out, and the wedges that remain renormalise to a full circle – the chart then reads as 100% of a whole it is not showing all of. AUserWarningnames the dropped categories when that happens. Cannot be combined withmin_share, whose"Other"bucket is not a category of the data and so cannot be named in an order.hue_order (sequence, optional) – Running order of the legend’s colour entries. Levels omitted from it keep their colour and are appended after the listed ones –
hue_orderreorders the key, it never decides which wedges are drawn. To drop categories, useorder.sort (bool, default False) – Order wedges by descending value. Cannot be combined with
order. Off by default so a pie keeps the category order of a bar panel drawn from the same frame.pull (float or dict, optional) –
How far wedges move out from the centre, as a fraction of the outer radius. Deliberately not a positional sequence.
A dict keyed by category pops out just the wedges it names: each is translated along its own mid-ray by
pulltimes the radius, as in matplotlib’sexplode, keeping its shape.A float explodes the whole chart evenly. With
tthat fraction of the radius, no wedge is translated: every wedge’s inner boundary moves out tor_inner + tand its rim tor_outer + t, and both its straight edges are inset so that every pair of neighbours is the same perpendicular distance2 * tapart, wide and thin wedges alike. Everything moves out bytand apart by2 * t. A pie opens a central hole of radiust(a donut’s hole grows byt), and labels follow the drawn radii. The price is shape: a translation along each wedge’s own mid-ray would keep it, but would open onlyt * sin(half-span)per side, so a thin wedge barely separates. Even for the two halves of a half-disc, where the edges and the gap match a translation exactly, the rim is an arc of radiusr_outer + tabout the chart’s centre, and so reaches up to abouttfurther than a translated half’s at its ends. A wedge too narrow at its rim for the full inset is capped rather than dropped, as forgap. A lone category’s 360-degree wedge has no edges to inset and draws as a full ring betweenr_inner + tandr_outer + t.0draws exactly what nopulldoes; a negative or non-finite float raisesValueError.gap (float, optional) – Gap between every pair of neighbouring wedges, in millimetres. Each wedge’s two straight edges are inset by
gap / 2parallel to themselves, so the band between two neighbours isgapwide along its whole length, for wide and thin wedges alike, while the arcs keep their radii. The width is measured between the outlines’ centre lines, so the unpainted band isgapless one outline width (linewidthpoints). No wedge is ever dropped: a wedge of at most 180 degrees is inset by no more thanr * sin(half-span / 2),rits drawn outer radius, so its rim arc keeps at least half its angular span – half its rim length, and at least half its rim chord. A wedge thin enough to be capped is drawn narrowed, and the band beside it is narrower by what it was spared:h + h_ito a full-inset neighbour, wherehis the full inset per edge andh_i <= hthe capped wedge’s, andh_i + h_jbetween two capped wedges; every other pair keeps the full width. With a floatpullthe two add up, so neighbours sitgapplus2 * tapart; a dictpullmoves each inset wedge as a whole. Defaults torcParams["pie.gap"](0.0, no gap).min_share (float, default 0.0) – Categories strictly below this fraction of the total merge into a single
"Other"wedge; a category sitting exactly on the threshold is kept. Applies only when at least two categories fall below it. Cannot be combined withorder.center_label (str or callable, optional) – Text for the donut hole. A callable receives the total. Ignored when
donut=0: a full pie has no hole to write in.aspect ({'cell', 'equal'}, default 'cell') –
'cell'matches the data limits to the axes’ millimetre ratio: the disc is sized to the shorter side of the cell and the longer side’s limits are stretched to match, so the axes box keeps the whole allocation on both axes and the surplus stays free for outside labels.'equal'uses matplotlib’s aspect constraint, which survives an interactive resize but shrinks the drawn box to a square, keeping onlymin(w, h) / max(w, h)of the allocation on whichever axis is longer. Both render a disc round to within a rendering pixel; measured ink ratios across 70x50, 90x40, 40x70, 30x80 and 60x60mm cells run 0.9942 to 1.0044.palette (str, dict, list, or Colormap, optional) –
Colour palette. For a categorical
hue, can be:str: seaborn palette name or publiplots palette namedict: explicit{hue_level: color}mapping, overlaid on the resolved defaults, so a partial dict recolours only the levels it nameslist: list of colours assigned in hue-level order
For a numeric
hue: a matplotlib colormap name ("viridis") or aColormap, used for the wedges and the colorbar alike, as inscatterplot; a dict or list raisesTypeError, as it does there, since a numeric hue has no discrete levels to assign colours to. Left asNone,pieplotbuilds its own light ramp running from near-white up tocolor– unlikescatterplot, whoseNonegives seaborn’s default ramp whatevercoloris.hatch (str, optional) –
Column name driving a second categorical dimension encoded via hatch textures – the texture-based analogue of
hue. Independent ofhue: pass the same column to both (hatch=x) to pattern each wedge by its own colour level, or a different column for a second key. Must be constant within a wedge, ashuemust.Patterns are drawn from
publiplots.HATCH_PATTERNSby default; density is controlled globally viapubliplots.set_hatch_mode()or overridden per-plot withhatch_map.hatch_map (dict, optional) – Mapping from hatch-column values to matplotlib hatch-pattern strings, overriding the per-
hatch_modedefaults, e.g.hatch_map={"control": "", "treated": "///"}.hatch_order (list, optional) – Running order of the legend’s hatch entries. Like
hue_orderit reorders the key and never decides which wedges are drawn; levels omitted from it are appended after the listed ones.color (str, optional) – Fixed colour used where no hue level supplies one: the colormap anchor for a continuous
huewhenpaletteisNone, and the swatch colour for a standalone hatch key. Falls back torcParams["color"].edgecolor (str, optional) – Explicit edge colour override. When
None(the default, also the default ofrcParams["edgecolor"]), each wedge’s edge matches its own face colour – publiplots’ double-layer transparent-fill styling. Set to a specific colour ("black") to outline every wedge the same way regardless of fill.linewidth (float, optional) – Width of the wedge outlines and hatch strokes. Defaults to
rcParams["edgewidth"].alpha (float, optional) – Transparency of the wedge fill (outlines stay fully opaque).
0= outlined wedges only;1= solid fill. Defaults torcParams["alpha"].legend (bool or dict, default=True) – Whether to render the legend. Accepts
boolordict[kind, bool]for per-kind control (e.g.legend={"hatch": False}hides just the hatch entry). Unlikebarplot,Falsesuppresses only the rendering: entries are stashed either way, so a later figure-levelpubliplots.legend()group can still claim them.legend_kws (dict, optional) – Extra kwargs forwarded to the legend builder. Notable keys:
inside=Truewithloc=...places the legend inside the axes using matplotlib’s corner-based placement;hue_label/hatch_labeloverride the title shown above each entry.annotate (bool or dict, optional) – If truthy, label each wedge with its share of the total as a percentage. Pass a
dictto forward options topubliplots.annotate():fmt(a format spec labels the raw value instead of the share),anchor("auto"/"inside"/"outside"),offset(mm),color,rotation(degrees, or"tangential"/"radial"),basis("total"/"parent"),leader("radial"/"elbow"/None),leader_gapandelbow_length(mm),avoid_overlap(move crowded outside labels apart) andlabel_spacing(mm between them).offsetand the leader options default to thepie.*rcParams.title (str or None, default="") – Plot title. Pass
Noneto leave the existing title unchanged.
- Return type:
Notes
huemeans colour here and nothing else. Inbarplotit also controls how marks group, because grouping has no other parameter; in a wedge chart the structure lives inx, so the two are separate.Examples
>>> ax = pp.pieplot(data=df, x="kind", y="n") >>> ax = pp.pieplot(data=df, x="kind", y="n", donut=0.55, ... center_label="{:,.0f}".format)