Axes in Julia
How to adjust axes properties in Julia - axes titles, styling and coloring axes and grid lines, ticks, tick labels and more.
This tutorial explain how to set the properties of [2-dimensional Cartesian axes], namely layout.xaxis
and layout.yaxis
.
Other kinds of subplots and axes are described in other tutorials:
3D axes The axis object is
layout.Scene
Polar axes. The axis object is
layout.Polar
See also the tutorials on subplots and multiple axes.
2-D Cartesian Axis Types and Auto-Detection
The different types of Cartesian axes are configured via the xaxis.type
or yaxis.type
attribute, which can take on the following values:
'linear'
as described in this page'log'
'date'
(see the tutorial on timeseries)'category'
'multicategory'
The axis type is auto-detected by looking at data from the first [trace] linked to this axis:
First check for
multicategory
, thendate
, thencategory
, else default tolinear
(log
is never automatically selected)multicategory
is just a shape test: is the array nested?date
andcategory
: require more than twice as many distinct date or category strings as distinct numbers in order to choose that axis type.Both of these test an evenly-spaced sample of at most 1000 values
Forcing an axis to be categorical
It is possible to force the axis type by setting explicitly xaxis_type
. In the example below the automatic X axis type would be linear
(because there are not more than twice as many unique strings as unique numbers) but we force it to be category
.
using PlotlyJS
trace = bar(x=["a", "a", "b", 3], y = [1,2,3,4])
layout = Layout(xaxis_type="category")
plot(trace, layout)
General Axis properties
The different groups of Cartesian axes properties are
title of the axis
tick values (locations of tick marks) and tick labels. Tick labels and grid lines are placed at tick values.
lines: grid lines (passing through tick values), axis lines, zero lines
range of the axis
domain of the axis
The examples on this page apply to axes of any type, but extra attributes are available for axes of type category
and axes of type date
.
Set and Style Axes Title Labels
Set axis title text
Axis titles are automatically set to the column names when using plot
and using DataFrame as input.
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "tips")
plot(df, x=:total_bill, y=:tip, color=:sex, mode="markers", type="scatter")
Axis titles can also be overridden using the [axis]_title
argument of Layout:
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "tips")
layout = Layout(
xaxis_title="Total Bill(\$)",
yaxis_title="Tip (\$)",
legend_title_text="Legend"
)
trace = scatter(df, x=:total_bill, y=:tip, color=:sex, mode="markers",)
plot(trace, layout)
Moving Tick Labels Inside the Plot
The ticklabelposition
attribute moves tick labels inside the plotting area, and modifies the auto-range behaviour to accommodate the labels.
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "stocks")
layout = Layout(ticklabelposition="inside top", title=missing)
trace = bar(df, x=:date, y=(df.GOOG .- 1))
plot(trace, layout)
Set axis title text with Graph Objects
Axis titles are set using the nested title
property of the x or y axis. Here is an example of creating a new figure and using Layout
, with magic underscore notation, to set the axis titles.
using PlotlyJS
trace = scatter(y=[1, 0], x=[0,1])
layout = Layout(xaxis_title="Time", yaxis_title="Value A")
plot(trace, layout)
Set axis title position
This example sets standoff
attribute to cartesian axes to determine the distance between the tick labels and the axis title. Note that the axis title position is always constrained within the margins, so the actual standoff distance is always less than the set or default value. By default automargin is True
in Plotly template for the cartesian axis, so the margins will be pushed to fit the axis title at given standoff distance.
using PlotlyJS
trace = scatter(
mode = "lines+markers",
y=[4, 1, 3],
x=["December", "January", "February"]
)
layout = Layout(
xaxis=attr(
tickangle=90,
title_text = "Month",
title_font_size=20,
title_standoff=25
),
yaxis=attr(
title_text = "Temperature",
title_standoff=25
)
)
plot(trace, layout)
Set axis title font
Here is an example that configures the font family, size, and color for the axis titles in a figure.
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "iris")
plot(
df, x=:sepal_width, y=:sepal_length, facet_col=:species,
mode="markers", kind="scatter",
Layout(
xaxis=attr(
title_text="sepal_width",
title_font=attr(size=18, family="Courier", color="crimson")
),
yaxis=attr(
title_text="sepal_length",
title_font=attr(size=18, family="Courier", color="crimson")
)
)
)
Tick Placement, Color, and Style
Set number of tick marks (and grid lines)
The approximate number of ticks displayed for an axis can be specified using the nticks
axis property.
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "iris")
plot(
df, x=:sepal_width, y=:sepal_length, facet_col=:species,
Layout(yaxis=attr(tickmode="auto",nticks=20)),
kind="scatter", mode="markers"
)
Set start position and distance between ticks
The tick0
and dtick
axis properties can be used to control to placement of axis ticks as follows: If specified, a tick will fall exactly on the location of tick0
and additional ticks will be added in both directions at intervals of dtick
.
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "iris")
plot(
df, x=:sepal_width, y=:sepal_length, facet_col=:species,
kind="scatter", mode="markers",
Layout(yaxis=attr(dtick=0.5, tick0=0.25)),
)
Set exact location of axis ticks
It is possible to configure an axis to display ticks at a set of predefined locations by setting the tickvals
property to an array of positions.
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "iris")
plot(
df, x=:sepal_width, y=:sepal_length, facet_col=:species,
kind="scatter", mode="markers",
Layout(yaxis_tickvals=[5.1, 5.9, 6.3, 7.5]),
)
Style tick marks
The ticks
axis property controls how the tick marks are draw. Set ticks
to "inside"
(to place ticks inside plotting area or "outside"
to place ticks outside the plotting area.
The appearance of these tick marks can be customized by setting their length (ticklen
), width (tickwidth
), and color (tickcolor
).
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "iris")
plot(
df, x=:sepal_width, y=:sepal_length, facet_col=:species,
kind="scatter", mode="markers",
Layout(
yaxis=attr(ticks="outside", tickwidth=2, tickcolor="crimson", ticklen=10, col=1),
xaxis=attr(ticks="outside", tickwidth=2, tickcolor="crimson", ticklen=10)
),
)
Toggling axis labels
The axis tick mark labels can be disabled by setting the showticklabels
axis property to false
.
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "iris")
plot(
df, x=:sepal_width, y=:sepal_length, facet_col=:species,
kind="scatter", mode="markers",
Layout(
yaxis=attr(showticklabels=false),
xaxis=attr(showticklabels=false)
),
)
Set axis label rotation and font
The orientation of the axis tick mark labels is configured using the tickangle
axis property. The value of tickangle
is the angle of rotation, in the clockwise direction, of the labels from vertical in units of degrees. The font family, size, and color for the tick labels are stored under the tickfont
axis property.
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "tips")
plot(
df, x=:sex, y=:tip, facet_col=:smoker,
type="histogram", histfunc="sum",
Layout(
xaxis=attr(tickangle=45, tickfont=attr(family="Rockwell", color="crimson", size=14))
)
)
Enumerated Ticks with Tickvals and Ticktext
The tickvals
and ticktext
axis properties can be used together to display custom tick label text at custom locations along an axis. They should be set to lists of the same length where the tickvals
list contains positions along the axis, and ticktext
contains the strings that should be displayed at the corresponding positions.
Here is an example.
using PlotlyJS, CSV, HTTP, Dates
# Load and filter Apple stock data for 2016
apple_df = CSV.File(
HTTP.get("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv").body
) |> DataFrame
apple_df_2016 = apple_df[year.(apple_df.Date) .== 2016, :]
layout = Layout(
# Set custom x-axis labels
xaxis=attr(
tickmode="array",
ticktext=["End of Q1", "End of Q2", "End of Q3", "End of Q4"],
tickvals=[Date("2016-04-01"), Date("2016-07-01"), Date("2016-10-01"), maximum(apple_df_2016.Date)],
),
# Prefix y-axis tick labels with dollar sign
yaxis_tickprefix="\$",
# Set figure title
title_text = "Apple Stock Price"
)
# Create figure and add line
plot(
apple_df_2016, x=:Date, y=Symbol("AAPL.High"),
kind="scatter", mode="lines",
layout
)
Axis lines: grid and zerolines
Toggling Axis grid lines
Axis grid lines can be disabled by setting the showgrid
property to False
for the x and/or y axis.
Here is an example of setting showgrid
to False
in the graph object figure constructor.
using PlotlyJS
plot(
scatter(mode="lines", y=[1, 0], x=[0,1]),
Layout(xaxis_showgrid=false, yaxis_showgrid=false)
)
Toggling Axis zero lines
The lines passing through zero can be disabled as well by setting the zeroline
axis property to False
using PlotlyJS
plot(scatter(mode="lines", y=[1, 0], x=[0,1]),
Layout(
xaxis_showgrid=false,
xaxis_zeroline=false,
yaxis_showgrid=false,
yaxis_zeroline=false
)
)
Styling and Coloring Axes and the Zero-Line
Styling axis lines
The showline
axis property controls the visibility of the axis line, and the linecolor
and linewidth
axis properties control the color and width of the axis line.
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "tips")
plot(
df, x=:sex, y=:tip, facet_col=:smoker,
kind="histogram", histfunc="sum",
Layout(
yaxis=attr(showline=true, linewidth=2, linecolor="black"),
xaxis=attr(showline=true, linewidth=2, linecolor="black")
)
)
Mirroring axis lines
Axis lines can be mirrored to the opposite side of the plotting area by setting the mirror
axis property to true
.
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "tips")
plot(
df, x=:sex, y=:tip, facet_col=:smoker,
kind="histogram", histfunc="sum",
Layout(
yaxis=attr(showline=true, linewidth=2, linecolor="black", mirror=true),
xaxis=attr(showline=true, linewidth=2, linecolor="black", mirror=true)
)
)
Styling grid lines
The width and color of axis grid lines are controlled by the gridwidth
and gridcolor
axis properties.
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "iris")
plot(
df, x=:sepal_width, y=:sepal_length, facet_col=:species,
kind="scatter", mode="markers",
Layout(
yaxis=attr(showgrid=true, gridwidth=1, gridcolor="LightPink"),
xaxis=attr(showgrid=true, gridwidth=1, gridcolor="LightPink")
),
)
Styling zero lines
The width and color of axis zero lines are controlled by the zerolinewidth
and zerolinecolor
axis properties.
Here is an example of configuring the zero line width and color for a simple figure using the update_xaxes
and update_yaxes
graph object figure methods.
using PlotlyJS
plot(scatter(y=[1, 0], x=[0,1]), Layout(
xaxis=attr(zeroline=true, zerolinewidth=2, zerolinecolor="LightPink"),
yaxis=attr(zeroline=true, zerolinewidth=2, zerolinecolor="LightPink")
))
Setting the Range of Axes Manually
The visible x and y axis range can be configured manually by setting the range
axis property to a list of two values, the lower and upper boundary.
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "iris")
plot(
df, x=:sepal_width, y=:sepal_length, facet_col=:species,
kind="scatter", mode="markers",
Layout(xaxis_range=[1.5, 4.5], yaxis_range=[3, 9]),
)
Disabling Pan/Zoom on Axes (Fixed Range)
Pan/Zoom can be disabled for a given axis by setting fixedrange
to True
.
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "iris")
plot(
df, x=:sepal_width, y=:sepal_length, facet_col=:species,
kind="scatter", mode="markers",
Layout(xaxis=attr(fixedrange=true),),
)
Fixed Ratio Axes
The scaleanchor
and scaleratio
axis properties can be used to force a fixed ratio of pixels per unit between two axes.
Here is an example of anchoring the scale of the x and y axis with a scale ratio of 1. Notice how the zoom box is constrained to prevent the distortion of the shape of the line plot.
using PlotlyJS
layout = Layout(
width=800,
height=500,
title="fixed-ratio axes",
yaxis=attr(scaleanchor="x", scaleratio=1)
)
trace = scatter(
x=[0,1,1,0,0,1,1,2,2,3,3,2,2,3],
y=[0,0,1,1,3,3,2,2,3,3,1,1,0,0]
)
plot(trace, layout)
Fixed Ratio Axes with Compressed domain
If an axis needs to be compressed (either due to its own scaleanchor
and scaleratio
or those of the other axis), constrain
determines how that happens: by increasing the "range" (default), or by decreasing the "domain".
using PlotlyJS
layout = Layout(
width=800, height=500,
title="fixed-ratio axes with compressed axes",
yaxis=attr( scaleanchor="x", scaleratio=1),
xaxis=attr(range=[-1,4], constrain="domain")
)
trace = scatter(
x=[0,1,1,0,0,1,1,2,2,3,3,2,2,3],
y=[0,0,1,1,3,3,2,2,3,3,1,1,0,0]
)
plot(trace, layout)
Decreasing the domain spanned by an axis
In the example below, the x and y axis are anchored together, and the range of the xaxis
is set manually. By default, plotly extends the range of the axis (overriding the range
parameter) to fit in the figure domain
. You can restrict the domain
to force the axis to span only the set range, by setting constrain='domain'
as below.
using PlotlyJS
layout = Layout(
width=800, height=500, title="fixed-ratio axes",
yaxis=attr(range=(-0.5, 3.5), constrain="domain"),
xaxis=attr(scaleanchor="x", scaleratio=1)
)
trace = scatter(
x=[0,1,1,0,0,1,1,2,2,3,3,2,2,3],
y=[0,0,1,1,3,3,2,2,3,3,1,1,0,0]
)
plot(trace, layout)
Fixed Ratio Axes with Compressed domain
If an axis needs to be compressed (either due to its own scaleanchor
and scaleratio
or those of the other axis), constrain
determines how that happens: by increasing the "range" (default), or by decreasing the "domain".
using PlotlyJS
layout = Layout(
width=800, height=500, title="fixed-ratio axes",
yaxis=attr(scaleanchor="x",scaleratio=1),
xaxis=attr(
range=[-1,4], # sets the range of xaxis
constrain="domain", # meanwhile compresses the xaxis by decreasing its "domain"
)
)
trace = scatter(
x=[0,1,1,0,0,1,1,2,2,3,3,2,2,3],
y=[0,0,1,1,3,3,2,2,3,3,1,1,0,0]
)
plot(trace, layout)
Reversed Axes
You can tell plotly's automatic axis range calculation logic to reverse the direction of an axis by setting the autorange
axis property to "reversed"
.
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "iris")
plot(
df, x=:sepal_width, y=:sepal_length, facet_col=:species,
kind="scatter", mode="markers",
Layout(yaxis_autorange="reversed"),
)
Reversed Axes with Range ( Min/Max ) Specified
The direction of an axis can be reversed when manually setting the range extents by specifying a list containing the upper bound followed by the lower bound (rather that the lower followed by the upper) as the range
axis property.
using PlotlyJS, CSV, DataFrames
df = dataset(DataFrame, "iris")
plot(
df, x=:sepal_width, y=:sepal_length, facet_col=:species,
kind="scatter", mode="markers",
Layout(yaxis_range=[9, 3]),
)
Axis range for log axis type
If you are using a log
type of axis and you want to set the range of the axis, you have to give the log10
value of the bounds.
using PlotlyJS
x = range(1, stop=200, length=30)
plot(
scatter(x=x, y=x.^3, range_x=[0.8, 250], mode="markers"),
Layout(
yaxis_type="log",
xaxis_type="log",
xaxis_range=[log10(0.8), log10(250)]
)
)
<code>nonnegative</code>, <code>tozero</code>, and <code>normal</code> Rangemode
The axis auto-range calculation logic can be configured using the rangemode
axis parameter.
If rangemode
is "normal"
(the default), the range is computed based on the min and max values of the input data. If "tozero"
, the range will always include zero. If "nonnegative"
, the range will not extend below zero, regardless of the input data.
using PlotlyJS
df = dataset(DataFrame, "iris")
plot(
df, x=:sepal_width, y=:sepal_length, facet_col=:species,
kind="scatter", mode="markers",
Layout(yaxis_range=[9, 3]),
)
Setting the domain of the axis
using PlotlyJS
plot(
scatter(
x=[0,1,1,0,0,1,1,2,2,3,3,2,2,3],
y=[0,0,1,1,3,3,2,2,3,3,1,1,0,0]
),
Layout(
yaxis_domain=(0.25, 0.75),
xaxis_domain=(0.25,0.75)
)
)
Reference
See https://plotly.com/julia/reference/layout/xaxis/ and https://plotly.com/julia/reference/layout/yaxis/ for more information and chart attribute options!