Box Plots in Python
A box plot (also called a box-and-whisker plot) summarizes a distribution with its median, quartiles, and
whiskers, and marks points beyond the whiskers as outliers. With xy you build
a boxplot in Python that compares several groups side by side and stays
interactive — pan, zoom, and hover to inspect every summary value.
Jump to creating a box plot, outliers and orientation, or options.
Create a Box Plot
Pass a list of arrays — one per group — to box, and label each group with
x. This is the minimal Python box plot:
Outliers and Orientation
Set show_outliers=True to draw individual points beyond the whiskers and tune
their marker with outlier_size. Switch orientation to "horizontal" when
group labels are long or when you want to read distributions left to right, and
use width to control how wide each box sits within its slot.
Horizontal Boxes with Outlier Markers
Flip the chart with orientation="horizontal", slim each box with width, and
enlarge the flagged points with show_outliers plus outlier_size.
Comparing Groups
Box plots shine when comparing many groups at a glance. Add one entry per group
to the list of arrays and give each a label through x; the medians and
quartiles line up on a shared axis so shifts in center and spread are easy to
compare.
Grouping from Long-Form Records
When observations arrive as one long array, pass a matching label array to
group= and box splits the values into per-group boxes automatically.
Box Plot Options
Pass column names with data= instead of arrays when your data is a table.
Related Charts
- Violin plots — show the full density shape, not just quartiles.
- Histograms — bin one distribution into bars.
- ECDF plots — the cumulative distribution without binning.
API Reference
xy.box_chart
A box/distribution chart composing `box` marks.
Props
| Prop | Type | Description |
|---|---|---|
*children | Component | Marks, axes, annotations, and chart chrome. |
title | Optional[str] | Title shown above the plot. |
width | int | str | Chart width in pixels or a CSS size such as ``"100%"``. |
height | int | str | Chart height in pixels or a CSS size such as ``"100%"``. |
padding | Union[float, Sequence[float], None] | Plot margins, as one value or a sequence of side values. Use zero for an edge-to-edge sparkline. |
data | TableLike | Chart-level data used by marks that omit their own ``data``. |
class_name | Optional[str] | CSS class applied to the chart container. |
class_names | Optional[dict[str, str]] | CSS classes keyed by stable chart DOM slot. |
style | Optional[dict[str, StyleValue]] | Inline style overrides for the chart container. |
styles | Optional[dict[str, dict[str, StyleValue]]] | Inline style mappings keyed by stable chart DOM slot. |
on_hover | Optional[Callable[[dict], None]] | Callback receiving hover event payloads. |
on_click | Optional[Callable[[dict], None]] | Callback receiving picked-mark click payloads. |
on_brush | Optional[Callable[[dict], None]] | Callback receiving brush event payloads. |
on_select | Optional[Callable[[Selection], None]] | Callback receiving data-space selections. |
on_view_change | Optional[Callable[[dict], None]] | Callback receiving viewport change payloads. |
hover | Optional[bool] | Whether pointer movement emits hover events. |
click | Optional[bool] | Whether picked marks emit click events. |
select | Optional[bool] | Whether shift-drag box selection is enabled. |
brush | Optional[bool] | Whether brush selection is enabled. |
crosshair | Optional[bool] | Whether plot-aligned hover guides are shown. |
navigation | Optional[bool] | Whether browser pan and zoom navigation is enabled. |
pan | Optional[bool] | Whether plain-drag panning is enabled. |
pan_axes | Optional[tuple[str, ...]] | Declared axis IDs translated by pan gestures. |
zoom | Optional[bool] | Whether viewport zoom is enabled. |
default_drag_action | Optional[DefaultDragAction] | Initial action performed by a plain plot drag. |
zoom_axes | Optional[tuple[str, ...]] | Declared axis IDs changed by zoom gestures and controls. |
zoom_limits | Optional[ZoomLimits] | Minimum and maximum magnification globally or by axis. |
wheel_zoom | Optional[bool] | Whether wheel and trackpad zoom is available. |
box_zoom | Optional[bool] | Whether box zoom is available as a drag action. |
zoom_buttons | Optional[bool] | Whether modebar Zoom In/Out commands are available. |
double_click_reset | Optional[bool] | Whether double-click restores ``reset_axes``. |
reset_axes | Optional[tuple[str, ...]] | Declared axis IDs restored by reset. |
link_group | Optional[str] | Identifier used to synchronize charts in the browser. |
link_axes | Optional[tuple[str, ...]] | Axes synchronized within the link group. |
FAQ
How do I make a box plot in Python?
Pass a list of arrays to xy.box(...), one per group, inside
xy.box_chart(...) and render it. Quartiles, whiskers, and axes are computed
for the whole box chart automatically.
How do I show outliers on a box plot?
Set show_outliers=True on box. Points beyond the whiskers are drawn
individually, and outlier_size controls their marker size.
How do I make a horizontal box plot?
Set orientation="horizontal" on box to turn the box graph on its side:
groups run down the y-axis and values spread along the x-axis.
What is the difference between a box plot and a violin plot?
A box plot shows summary statistics — median, quartiles, and whiskers — while a violin plot shows the full estimated density, so it reveals multi-modal shapes a box plot hides.