Subplots in Julia
How to make subplots in with Plotly's Julia graphing library. Examples of stacked, custom-sized, gridded, and annotated subplots.
Simple Subplot
Figures with subplots are created using Julia's array creation syntax. To create a Figure with one row and two columns of subplots, use the syntax [plot(...) plot(...)]
using PlotlyJS
p1 = plot(scatter(x=1:3, y=4:6))
p2 = plot(scatter(x=20:40, y=50:70))
p = [p1 p2]
relayout!(p, title_text="Side by side layout (1 x 2)")
p
Stacked Subplots
Here is an example of creating a figure with subplots that are stacked on top of each other since there are 3 rows and 1 column in the subplot layout.
using PlotlyJS
make_plot() = plot(scatter(x=1:4, y=rand(4)))
p = [make_plot(); make_plot(); make_plot()]
relayout!(p, height=600, width=600, title_text="Stacked Subplots")
p
Multiple Subplots
Here is an example of creating a 2 x 2 subplot grid and populating each subplot with a single scatter
trace.
using PlotlyJS
make_plot() = plot(scatter(x=1:4, y=rand(4)))
[
make_plot() make_plot()
make_plot() make_plot()
]
Or, equivalently
using PlotlyJS
make_plot() = plot(scatter(x=1:4, y=rand(4)))
[make_plot() make_plot(); make_plot() make_plot()]
Multiple Subplots with Titles
To add titles to your subplots, add a title to the Layout of each original plot
Here is an example of adding subplot titles to a 2 x 2 subplot grid of scatter traces.
using PlotlyJS
make_scatter() = scatter(x=1:4, y=rand(4))
p1 = plot(make_scatter(), Layout(title="subplot 1"))
p2 = plot(make_scatter(), Layout(title="subplot 2"))
p3 = plot(make_scatter(), Layout(title="subplot 3"))
p4 = plot(make_scatter(), Layout(title="subplot 4"))
p = [p1 p2; p3 p4]
relayout!(p, height=500, width=700, title_text="Multiple Subplots with Titles")
p
The Subplots
type
The array construction pun is helpful for quickly creating grids of regularly spaced subplots.
To do more advanced subplot custimization, we have the Subplots
type.
Using the Subplots
you can control things like the relative size of subplots, created nested grids of subplots, share x or y axes, etc.
There are two usage patterns for using the Subplots
type:
Pattern 1
The first pattern is to directly create an instance of Subplots
, then create a Layout
, then create an empty plot and add traces
using PlotlyJS
sp = Subplots(kwargs...)
layout = Layout(sp)
p = plot(layout)
add_trace!(p, ...)
Pattern 2
The second pattern is to use the make_subplots
helper function that does that for you.
using PlotlyJS
p = make_subplots(kwargs....)
add_trace!(p, ...)
Note that make_subplots
takes all the same arguments as Subplots
.
Below are some examples of how this works.
Subplots with Shared X-Axes
The shared_xaxes
argument to make_subplots
can be used to link the x axes of subplots in the resulting figure. The vertical_spacing
argument is used to control the vertical spacing between rows in the subplot grid.
Here is an example that creates a figure with 3 vertically stacked subplots with linked x axes. A small vertical spacing value is used to reduce the spacing between subplot rows.
using PlotlyJS
p = make_subplots(rows=3, cols=1, shared_xaxes=true, vertical_spacing=0.02)
add_trace!(p, scatter(x=0:2, y=10:12), row=3, col=1)
add_trace!(p, scatter(x=2:4, y=100:10:120), row=2, col=1)
add_trace!(p, scatter(x=3:5, y=1000:100:1200), row=1, col=1)
relayout!(p, title_text="Stacked Subplots with Shared X-Axes")
p
Subplots with Shared Y-Axes
The shared_yaxes
argument to make_subplots
can be used to link the y axes of subplots in the resulting figure.
Here is an example that creates a figure with a 2 x 2 subplot grid, where the y axes of each row are linked.
using PlotlyJS
p = make_subplots(rows=3, cols=2, shared_yaxes=true)
add_trace!(p, scatter(x=0:2, y=10:12), row=1, col=1)
add_trace!(p, scatter(x=20:10:40, y=1:3), row=1, col=2)
add_trace!(p, scatter(x=3:5, y=600:100:800), row=2, col=1)
add_trace!(p, scatter(x=3:5, y=1000:100:1200), row=2, col=2)
relayout!(p, title_text="Multiple Subplots with Shared Y-Axes")
p
Custom Sized Subplot with Subplot Titles
The specs
argument to make_subplots
is used to configure per-subplot options. specs
must be a Matrix
with dimensions that match those provided as the rows
and cols
arguments. The elements of specs
may either be missing
, indicating no subplot should be initialized starting with this grid cell, or an instance of Spec
containing subplot options. The colspan
subplot option specifies the number of grid columns that the subplot starting in the given cell should occupy. If unspecified, colspan
defaults to 1.
Here is an example that creates a 2 by 2 subplot grid containing 3 subplots. The subplot specs
element for position (2, 1) has a colspan
value of 2, causing it to span the full figure width. The subplot specs
element for position (2, 2) is None
because no subplot begins at this location in the grid.
using PlotlyJS
p = make_subplots(
rows=2, cols=2,
specs=[Spec() Spec(); Spec(colspan=2) missing],
subplot_titles=["First Subplot" "Second Subplot"; "Third Subplot" missing]
)
add_trace!(p, scatter(x=[1, 2], y=[1, 2]), row=1, col=1)
add_trace!(p, scatter(x=[1, 2], y=[1, 2]), row=1, col=2)
add_trace!(p, scatter(x=[1, 2, 3], y=[2, 1, 2]), row=2, col=1)
relayout!(p, showlegend=false, title_text="Specs with Subplot Title")
p
Multiple Custom Sized Subplots
Here is an example that uses the rowspan
and colspan
subplot options to create a custom subplot layout with subplots of mixed sizes. The print_grid
argument is set to True
so that the subplot grid is printed to the screen.
using PlotlyJS
p = make_subplots(
rows=5, cols=2,
specs=[Spec() Spec(rowspan=2)
Spec() missing
Spec(rowspan=2, colspan=2) missing
missing missing
Spec() Spec()]
)
add_trace!(p, scatter(x=[1, 2], y=[1, 2], name="(1,1)"), row=1, col=1)
add_trace!(p, scatter(x=[1, 2], y=[1, 2], name="(1,2)"), row=1, col=2)
add_trace!(p, scatter(x=[1, 2], y=[1, 2], name="(2,1)"), row=2, col=1)
add_trace!(p, scatter(x=[1, 2], y=[1, 2], name="(3,1)"), row=3, col=1)
add_trace!(p, scatter(x=[1, 2], y=[1, 2], name="(5,1)"), row=5, col=1)
add_trace!(p, scatter(x=[1, 2], y=[1, 2], name="(5,2)"), row=5, col=2)
relayout!(p, height=600, width=600, title_text="specs examples")
p
Subplots Types
By default, the make_subplots
function assumes that the traces that will be added to all subplots are 2-dimensional cartesian traces (e.g. scatter
, bar
, histogram
, violin
, etc.). Traces with other subplot types (e.g. scatterpolar
, scattergeo
, parcoords
, etc.) are supported by specifying the kind
subplot option in the specs
argument to make_subplots
.
Here are the possible values for the kind
option:
"xy"
: 2D Cartesian subplot type for scatter, bar, etc. This is the default if notype
is specified."scene"
: 3D Cartesian subplot for scatter3d, cone, etc."polar"
: Polar subplot for scatterpolar, barpolar, etc."ternary"
: Ternary subplot for scatterternary."mapbox"
: Mapbox subplot for scattermapbox."domain"
: Subplot type for traces that are individually positioned. pie, parcoords, parcats, etc.trace type: A trace type name (e.g.
"bar"
,"scattergeo"
,"carpet"
,"mesh"
, etc.) which will be used to determine the appropriate subplot type for that trace.
Here is an example that creates and populates a 2 x 2 subplot grid containing 4 different subplot types.
using PlotlyJS
p = make_subplots(
rows=2, cols=2,
specs=[
Spec(kind="xy") Spec(kind="polar")
Spec(kind="domain") Spec(kind="scene")
]
)
add_trace!(p, bar(y=[2, 3, 1]), row=1, col=1)
add_trace!(p, barpolar(theta=[0, 45, 90], r=[2, 3, 1]), row=1, col=2)
add_trace!(p, pie(values=[2, 3, 1]), row=2, col=1)
add_trace!(p,
scatter3d(x=[2, 3, 1], y=[0, 0, 0], z=[0.5, 1, 2], mode="lines"),
row=2, col=2
)
relayout!(p, height=700, showlegend=false)
nothing
Low Level API
The third and last approach for creating subplots is to use the low level plotly.js api.
When using this API you explicitly place each of the axes on the figure and link them to one another.
You also are responsible for assigned traces to a particular pair of axes.
This is the most verbose of the methods for creating charts with multiple subplots, but it is also the most powerful.
The other methods (array creation syntax and make_subplots
) use this API under the hood.
Side by Side Subplot (low-level API)
using PlotlyJS
plot(
[
scatter(x=1:3, y=4:6),
scatter(x=20:10:30, y=50:10:70, xaxis="x2", yaxis="y2")
],
Layout(xaxis_domain=[0, 0.7], xaxis2_domain=[0.8, 1], yaxis2_anchor="x2")
)
Subplots with shared axes (low-level API)
using PlotlyJS
plot(
[
scatter(x=1:3, y=4:6),
scatter(x=20:10:30, y=[5, 5, 5], xaxis="x2", yaxis="y"),
scatter(x=2:4, y=600:100:800, xaxis="x", yaxis="y3"),
scatter(x=4000:1000:6000, y=7000:1000:9000, xaxis="x4", yaxis="y4"),
],
Layout(
xaxis_domain=[0, 0.45],
yaxis_domain=[0, 0.45],
xaxis2_domain=[0.55, 1],
xaxis4=attr(domain=[0.55, 1], anchor="y4"),
yaxis3_domain=[0.55, 1],
yaxis4=attr(domain=[0.55, 1], anchor="x4")
)
)
Stacked Subplots with a Shared X-Axis (low-level API)
using PlotlyJS
plot(
[
scatter(x=0:2, y=10:12),
scatter(x=2:4, y=100:10:120, yaxis="y2"),
scatter(x=3:5, y=1000:100:1200, yaxis="y3"),
],
Layout(
yaxis_domain=[0, 0.33],
legend_traceorder="reversed",
yaxis2_domain=[0.33, 0.66],
yaxis3_domain=[0.66, 1]
)
)
Reference
All of the x-axis properties are found here: https://plotly.com/julia/reference/XAxis/ All of the y-axis properties are found here: https://plotly.com/julia/reference/YAxis/
To get more help, see the docstring for make_subplots
using PlotlyJS
@doc make_subplots