# hexbin

``hexbin(xs, ys; kwargs...)``

Plots a heatmap with hexagonal bins for the observations `xs` and `ys`.

## Attributes

### Specific to `Hexbin`

• `bins = 20`: If an `Int`, sets the number of bins in x and y direction. If a `Tuple{Int, Int}`, sets the number of bins for x and y separately.

• `cellsize = nothing`: If a `Real`, makes equally-sided hexagons with width `cellsize`. If a `Tuple{Real, Real}` specifies hexagon width and height separately.

• `threshold::Int = 1`: The minimal number of observations in the bin to be shown. If 0, all zero-count hexagons fitting into the data limits will be shown.

• `scale = identity`: A function to scale the number of observations in a bin, eg. log10.

### Generic

• `colormap::Union{Symbol, Vector{<:Colorant}} = :viridis`

• `colorrange::Tuple(<:Real,<:Real} = Makie.automatic` sets the values representing the start and end points of `colormap`.

## Examples

### Setting the number of bins

Setting `bins` to an integer sets the number of bins to this value for both x and y. The minimum number of bins in one dimension is 2.

``````using CairoMakie

using Random
Random.seed!(1234)

f = Figure(resolution = (800, 800))

x = rand(300)
y = rand(300)

for i in 2:5
ax = Axis(f[fldmod1(i-1, 2)...], title = "bins = \$i", aspect = DataAspect())
hexbin!(ax, x, y, bins = i)
wireframe!(ax, Rect2f(Point2f.(x, y)), color = :red)
scatter!(ax, x, y, color = :red, markersize = 5)
end

f`````` You can also pass a tuple of integers to control x and y separately.

``````using CairoMakie

using Random
Random.seed!(1234)

f = Figure(resolution = (800, 800))

x = rand(300)
y = rand(300)

for i in 2:5
ax = Axis(f[fldmod1(i-1, 2)...], title = "bins = (3, \$i)", aspect = DataAspect())
hexbin!(ax, x, y, bins = (3, i))
wireframe!(ax, Rect2f(Point2f.(x, y)), color = :red)
scatter!(ax, x, y, color = :red, markersize = 5)
end

f`````` ### Setting the size of cells

You can also control the cell size directly by setting the `cellsize` keyword. In this case, the `bins` setting is ignored.

The height of a hexagon is larger than its width. This is why setting the same size for x and y will result in uneven hexagons.

``````using CairoMakie

using Random
Random.seed!(1234)

f = Figure(resolution = (800, 800))

x = rand(300)
y = rand(300)

for (i, cellsize) in enumerate([0.1, 0.15, 0.2, 0.25])
ax = Axis(f[fldmod1(i, 2)...], title = "cellsize = (\$cellsize, \$cellsize)", aspect = DataAspect())
hexbin!(ax, x, y, cellsize = (cellsize, cellsize))
wireframe!(ax, Rect2f(Point2f.(x, y)), color = :red)
scatter!(ax, x, y, color = :red, markersize = 5)
end

f`````` To get evenly sized hexagons, set the cell size to a single number. This number defines the cell width, the height will be computed as `2 * step_x / sqrt(3)`. Note that the visual appearance of the hexagons will only be even if the x and y axis have the same scaling, which is why we use `aspect = DataAspect()` in these examples.

``````using CairoMakie

using Random
Random.seed!(1234)

f = Figure(resolution = (800, 800))

x = rand(300)
y = rand(300)

for (i, cellsize) in enumerate([0.1, 0.15, 0.2, 0.25])
ax = Axis(f[fldmod1(i, 2)...], title = "cellsize = \$cellsize", aspect = DataAspect())
hexbin!(ax, x, y, cellsize = cellsize)
wireframe!(ax, Rect2f(Point2f.(x, y)), color = :red)
scatter!(ax, x, y, color = :red, markersize = 5)
end

f`````` ### Hiding hexagons with low counts

All hexagons with a count lower than `threshold` will be removed:

``````using CairoMakie

using Random
Random.seed!(1234)

f = Figure(resolution = (800, 800))

x = randn(100000)
y = randn(100000)

for (i, threshold) in enumerate([1, 10, 100, 500])
ax = Axis(f[fldmod1(i, 2)...], title = "threshold = \$threshold", aspect = DataAspect())
hexbin!(ax, x, y, cellsize = 0.4, threshold = threshold)
end
f`````` ### Changing the scale of the number of observations in a bin

You can pass a scale function to via the `scale` keyword, which will be applied to the bin counts before plotting.

``````using CairoMakie

using Random
Random.seed!(1234)

x = randn(100000)
y = randn(100000)

f = Figure()
hexbin(f[1, 1], x, y, bins = 40,
axis = (aspect = DataAspect(), title = "scale = identity"))
hexbin(f[1, 2], x, y, bins = 40, scale=log10,
axis = (aspect = DataAspect(), title = "scale = log10"))
f`````` ### Showing zero count hexagons

By setting `threshold = 0`, all hexagons that fit into the limits of the input data are shown. In this example, we add a transparent color to the start of the colormap and stroke each hexagon so the empty hexagons are visible but not too distracting.

``````using CairoMakie

using DelimitedFiles

f, ax, hb = hexbin(a,
cellsize = 6,
axis = (; aspect = DataAspect()),
threshold = 0,
colormap = [Makie.to_color(:transparent); Makie.to_colormap(:viridis)],
strokewidth = 0.5,
strokecolor = :gray50,
scale = Makie.pseudolog10)

tightlimits!(ax)

Colorbar(f[1, 2], hb,
label = "Number of airports",
ticks = (0:3, ["0", "10", "100", "1000"]),
height = Relative(0.5)
)
f`````` 