# Axis

## Creating an Axis

The `Axis`

is a 2D axis that works well with automatic layouts. Here's how you create one

```
using CairoMakie
f = Figure(resolution = (1200, 900))
ax = Axis(f[1, 1], xlabel = "x label", ylabel = "y label",
title = "Title")
f
```

## Plotting into an Axis

You can use all the normal mutating 2D plotting functions with an `Axis`

. These functions return the created plot object. Omitting the `ax`

argument plots into the `current_axis()`

, which is usually the axis that was last created.

```
lineobject = lines!(ax, 0..10, sin, color = :red)
scatobject = scatter!(0:0.5:10, cos, color = :orange)
f
```

## Deleting plots

You can delete a plot object directly via `delete!(ax, plotobj)`

. You can also remove all plots with `empty!(ax)`

.

```
using CairoMakie
f = Figure(resolution = (1200, 500))
axs = [Axis(f[1, i]) for i in 1:3]
scatters = map(axs) do ax
[scatter!(ax, 0:0.1:10, x -> sin(x) + i) for i in 1:3]
end
delete!(axs[2], scatters[2][2])
empty!(axs[3])
f
```

## Setting Axis limits and reversing axes

You can set axis limits with the functions `xlims!`

, `ylims!`

or `limits!`

. The numbers are meant in the order left right for `xlims!`

, and bottom top for `ylims!`

. Therefore, if the second number is smaller than the first, the respective axis will reverse. You can manually reverse an axis by setting `ax.xreversed = true`

or `ax.yreversed = true`

.

Note that if you enforce an aspect ratio between x-axis and y-axis using `autolimitaspect`

, the values you set with these functions will probably not be exactly what you get, but they will be changed to fit the chosen ratio.

```
using CairoMakie
f = Figure(resolution = (1200, 900))
axes = [Axis(f[i, j]) for j in 1:3, i in 1:2]
for (i, ax) in enumerate(axes)
ax.title = "Axis $i"
poly!(ax, Point2f0[(9, 9), (3, 1), (1, 3)],
color = cgrad(:inferno, 6, categorical = true)[i])
end
xlims!(axes[1], [0, 10]) # as vector
xlims!(axes[2], 10, 0) # separate, reversed
ylims!(axes[3], 0, 10) # separate
ylims!(axes[4], (10, 0)) # as tuple, reversed
limits!(axes[5], 0, 10, 0, 10) # x1, x2, y1, y2
limits!(axes[6], BBox(0, 10, 0, 10)) # as rectangle
f
```

When you create a new plot in an axis, `reset_limits!(ax)`

is called, which adjusts the limits to the new bounds. If you have previously set limits with `limits!`

, `xlims!`

or `ylims!`

, these limits are not overridden by the new plot. If you want to override the manually set limits, call `autolimits!(ax)`

to compute completely new limits from the axis content.

The user-defined limits are stored in `ax.limits`

. This can either be a tuple with two entries, where each entry can be either `nothing`

or a tuple with numbers `(low, high)`

.It can also be a tuple with four numbers `(xlow, xhigh, ylow, yhigh)`

. You can pass this directly when creating a new axis. The same observable `limits`

is also set using `limits!`

, `xlims!`

and `ylims!`

, or reset to `(nothing, nothing)`

using `autolimits!`

.

```
using CairoMakie
f = Figure(resolution = (800, 400))
lines(f[1, 1], 0..10, sin)
lines(f[1, 2], 0..10, sin, axis = (limits = (0, 10, -1, 1),))
f
```

## Modifying ticks

To control ticks, you can set the axis attributes `xticks/yticks`

and `xtickformat/ytickformat`

.

You can overload one or more of these three functions to implement custom ticks:

```
tickvalues, ticklabels = MakieLayout.get_ticks(ticks, formatter, vmin, vmax)
tickvalues = MakieLayout.get_tickvalues(ticks, vmin, vmax)
ticklabels = MakieLayout.get_ticklabels(formatter, tickvalues)
```

If you overload `get_ticks`

, you have to compute both tickvalues and ticklabels directly as a vector of floats and strings, respectively. Otherwise the result of `get_tickvalues`

is passed to `get_ticklabels`

by default. The limits of the respective axis are passed as `vmin`

and `vmax`

.

A couple of behaviors are implemented by default. You can specify static ticks by passing an iterable of numbers. You can also pass a tuple with tick values and tick labels directly, bypassing the formatting step.

As a third option you can pass a function taking minimum and maximum axis value as arguments and returning either a vector of tickvalues which are then passed to the current formatter, or a tuple with tickvalues and ticklabels which are then used directly.

For formatting, you can pass a function which takes a vector of numbers and outputs a vector of strings. You can also pass a format string which is passed to `Formatting.format`

from Formatting.jl, where you can mix the formatted numbers with other text like in `"{:.2f}ms"`

.

### Predefined ticks

The default tick type is `LinearTicks(n)`

, where `n`

is the target number of ticks which the algorithm tries to return.

```
using CairoMakie
fig = Figure(resolution = (1200, 900))
for (i, n) in enumerate([2, 5, 9])
lines(fig[i, 1], 0..20, sin, axis = (xticks = LinearTicks(n),))
end
fig
```

There's also `WilkinsonTicks`

which uses the alternative Wilkinson algorithm.

`MultiplesTicks`

can be used when an axis should be marked at multiples of a certain number. A common scenario is plotting a trigonometric function which should be marked at pi intervals.

```
using CairoMakie
lines(0..20, sin, axis = (xticks = MultiplesTicks(4, pi, "π"),))
```

Here are a couple of examples that show off different settings for ticks and formats.

```
using CairoMakie
scene, layout = layoutscene(resolution = (1200, 900))
axes = layout[] = [Axis(scene) for i in 1:2, j in 1:2]
xs = LinRange(0, 2pi, 50)
for (i, ax) in enumerate(axes)
ax.title = "Axis $i"
lines!(ax, xs, sin.(xs))
end
axes[1].xticks = 0:6
axes[2].xticks = 0:pi:2pi
axes[2].xtickformat = xs -> ["$(x/pi)π" for x in xs]
axes[3].xticks = (0:pi:2pi, ["start", "middle", "end"])
axes[4].xticks = 0:pi:2pi
axes[4].xtickformat = "{:.2f}ms"
axes[4].xlabel = "Time"
scene
```

## Minor ticks and grids

You can show minor ticks and grids by setting `x/yminorticksvisible = true`

and `x/yminorgridvisible = true`

which are off by default. You can set size, color, width, align etc. like for the normal ticks, but there are no labels. The `x/yminorticks`

attributes control how minor ticks are computed given major ticks and axis limits. For that purpose you can create your own minortick type and overload `MakieLayout.get_minor_tickvalues(minorticks, tickvalues, vmin, vmax)`

.

The default minor tick type is `IntervalsBetween(n, mirror = true)`

where `n`

gives the number of intervals each gap between major ticks is divided into with minor ticks, and `mirror`

decides if outside of the major ticks there are more minor ticks with the same intervals as the adjacent gaps.

```
using CairoMakie
theme = Attributes(
Axis = (
xminorticksvisible = true,
yminorticksvisible = true,
xminorgridvisible = true,
yminorgridvisible = true,
)
)
fig = with_theme(theme) do
fig = Figure(resolution = (800, 800))
axs = [Axis(fig[fldmod1(n, 2)...],
title = "IntervalsBetween($(n+1))",
xminorticks = IntervalsBetween(n+1),
yminorticks = IntervalsBetween(n+1)) for n in 1:4]
fig
end
fig
```

## Hiding Axis spines and decorations

You can hide all axis elements manually, by setting their specific visibility attributes to `false`

, like `xticklabelsvisible`

, but that can be tedious. There are a couple of convenience functions for this.

To hide spines, you can use `hidespines!`

.

```
using CairoMakie
f = Figure(resolution = (1200, 900))
ax1 = Axis(f[1, 1], title = "Axis 1")
ax2 = Axis(f[1, 2], title = "Axis 2")
hidespines!(ax1)
hidespines!(ax2, :t, :r) # only top and right
f
```

To hide decorations, you can use `hidedecorations!`

, or the specific `hidexdecorations!`

and `hideydecorations!`

. When hiding, you can set `label = false`

, `ticklabels = false`

, `ticks = false`

, `grid = false`

, `minorgrid = false`

or `minorticks = false`

as keyword arguments if you want to keep those elements. It's common, e.g., to hide everything but the grid lines in facet plots.

```
using CairoMakie
f = Figure(resolution = (1200, 700))
ax1 = Axis(f[1, 1], title = "Axis 1")
ax2 = Axis(f[1, 2], title = "Axis 2")
ax3 = Axis(f[1, 3], title = "Axis 3")
hidedecorations!(ax1)
hidexdecorations!(ax2, grid = false)
hideydecorations!(ax3, ticks = false)
f
```

## Controlling Axis aspect ratios

If you're plotting images, you might want to force a specific aspect ratio of an axis, so that the images are not stretched. The default is that an axis uses all of the available space in the layout. You can use `AxisAspect`

and `DataAspect`

to control the aspect ratio. For example, `AxisAspect(1)`

forces a square axis and `AxisAspect(2)`

results in a rectangle with a width of two times the height. `DataAspect`

uses the currently chosen axis limits and brings the axes into the same aspect ratio. This is the easiest to use with images. A different aspect ratio can only reduce the axis space that is being used, also it necessarily has to break the layout a little bit.

```
using CairoMakie
using FileIO
f = Figure(resolution = (1200, 900))
axes = [Axis(f[i, j]) for i in 1:2, j in 1:3]
tightlimits!.(axes)
img = rotr90(load("../assets/cow.png"))
for ax in axes
image!(ax, img)
end
axes[1, 1].title = "Default"
axes[1, 2].title = "DataAspect"
axes[1, 2].aspect = DataAspect()
axes[1, 3].title = "AxisAspect(418/348)"
axes[1, 3].aspect = AxisAspect(418/348)
axes[2, 1].title = "AxisAspect(1)"
axes[2, 1].aspect = AxisAspect(1)
axes[2, 2].title = "AxisAspect(2)"
axes[2, 2].aspect = AxisAspect(2)
axes[2, 3].title = "AxisAspect(0.5)"
axes[2, 3].aspect = AxisAspect(0.5)
f
```