Hexbin Plots in Python
A hexbin plot (also called a hexbin chart or hexbin graph) in python
aggregates a dense point cloud into a hexagonal grid, coloring each cell by how
many points fall inside it. With xy you build
an interactive hexbin from millions of points without overplotting: pan, zoom,
and hover work by default, and dense regions stay legible.
Jump to creating a hexbin, value channels, or the options table.
Create a Hexbin Plot
Pass paired x and y arrays to hexbin. It aggregates large point clouds into a
grid of hexagonal cells, so a scatter that would smear into a solid blob becomes
a readable density map:
Tune the Grid and Add a Colorbar
Pass a (nx, ny) tuple to gridsize to control cell resolution per axis,
raise mincnt to clear out sparse background cells, swap the colormap, and
add an xy.colorbar() so the count scale is readable:
Color Cells by a Mean Value
Instead of counting points, pass a C value array and a reduce_C_function
such as np.mean — each cell is colored by the reduced value of the samples
that land in it, turning scattered measurements into a surface:
Count Bins and Value Channels
By default each cell is colored by its point count. Raise gridsize for finer
cells and use mincnt to hide sparse cells below a threshold. To color by a
quantity instead of a raw count, pass a C value array and set
reduce_C_function (for example np.mean) to reduce the values that fall in
each cell into a single color.
Hexbin Options
Add to show the value-to-color
scale. Pass column names with data= instead of arrays when your data is a
table.
Related Charts
- Heatmaps — color a regular grid of precomputed values.
- Contour plots — draw iso-value lines over a density field.
- Scatter charts — plot individual points when the cloud is small enough to read.
API Reference
xy.hexbin_chart
A hexbin chart composing `hexbin` 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 hexbin plot in Python?
Pass paired x and y arrays to xy.hexbin(x, y) inside xy.hexbin_chart(...) and
render it. Cells are colored by point count automatically.
When should I use a hexbin instead of a scatter?
Use a hexbin when a scatter overplots — tens of thousands of points or more that smear into a solid mass. Hexbin aggregates them into a density grid you can read.
How do I color a hexbin by a value instead of a count?
Pass a C value array and set reduce_C_function, such as np.mean, to reduce
the values in each cell into a single color.
How do I hide sparse hexagons?
Set mincnt to the minimum number of points a cell must contain before it is
drawn, which clears out near-empty background cells.