Creating a MultiFigure
#
To create a MultiFigure
, you first have to decide what size you want the canvas’ grid to be. You control this by setting the values of num_rows
and num_cols
as shown in the figure below. This grid is then used to place each set of axes in the MultiFigure. These values are independent of the size of the canvas.
To create a MultiFigure, simply use the following line of code:
multifigure = gl.MultiFigure(2, 2) # 2 rows, 2 columns
You can add create Figure
objects and add them to the MultiFigure
while specifying its position and size within the grid:
# Create the figures
figure1 = gl.Figure()
figure2 = gl.Figure()
# (row start, column start, rows spanned, columns spanned)
# This will create a 1x1 SubFigure in the top left corner of the grid
multifigure.add_figure(figure1, 0, 0, 1, 1)
# Now we create a SubFigure covering the right column of the grid
multifigure.add_figure(figure2, 0, 1, 2, 1) # Spans 2 rows, 1 column
# Bottom left stays empty
Elements can be added to Figure
objects as usual using the add_elements()
method. It is important to note that a single set of axes is not confined to a single square on the grid; it can span multiple squares. This means it is possible to align the individual sets of axes however you want. For example, here is how you could insert 3 subfigures in 2 rows with the one on the second row being centered:
# Create the curves
sine = gl.Curve.from_function(lambda x: np.sin(x), 0, 2 * np.pi, label="sine")
cosine = gl.Curve.from_function(lambda x: np.cos(x), 0, 2 * np.pi, label="cosine")
tangent = gl.Curve.from_function(
lambda x: np.tan(x), 0, 2 * np.pi, label="tangent", number_of_points=1000
)
# Create the figures and add the elements
figure1 = gl.Figure()
figure1.add_elements(sine)
figure2 = gl.Figure()
figure2.add_elements(cosine)
figure3 = gl.Figure()
figure3.add_elements(tangent)
# Create the MultiFigure and add the figures to it
multifigure = gl.MultiFigure(2, 4, size=(11, 8)) # 2 rows, 4 columns
multifigure.add_figure(figure1, 0, 0, 1, 2) # Spans the first 2 columns of the top row
multifigure.add_figure(figure2, 0, 2, 1, 2) # Spans the last 2 columns of the top row
multifigure.add_figure(figure3, 1, 1, 1, 2) # Spans the middle 2 columns of the bottom row
multifigure.show()
As you can see in the above figure, there are labels (a), b), c)) next to each subfigure. These reference labels can be helpful to refer to a specific subfigure when inserting in a document. The boolean parameter reference_labels
(in the MultiFigure
constructor) can turn these on or off.
Some simple MultiFigure layouts have helper methods to make it easier to create them. For example, you can create a horizontal row or vertical stack of figures using the from_row()
or from_stack()
classmethods respectively:
multifigure_row = gl.MultiFigure.from_row([figure1, figure2, figure3], size=(10, 5))
multifigure_stack = gl.MultiFigure.from_stack([figure1, figure2, figure3], size=(5, 10))
The from_grid()
classmethod can be used to create a MultiFigure from a list of figures and given dimensions. For example, the following code creates a 2x2 MultiFigure from a list of 4 figures:
figure4 = gl.Figure()
figure4.add_elements(sine, cosine, tangent)
multifigure_grid = gl.MultiFigure.from_grid([figure1, figure2, figure3, figure4], (2, 2), size=(10, 10), title="My MultiFigure")
Legends in MultiFigures#
The legends in a MultiFigure can be added separately for every subfigure or as a single legend combining the labels of every plot. This option is controlled by the general_legend
parameter in the show()
and save()
methods. By default, it is set to False
so that each subfigure controls its own legend. The two images below illustrate the different legend options.
Styles and Customization in MultiFigures#
Figure style and customizations can get a bit confusing when working with MultiFigure
objects. Here is a brief overview:
The
figure_style
chosen in theMultiFigure
constructor is applied to everyFigure
in the MultiFigure. Anyfigure_style
specified in the individualFigure
objects is ignored when displaying or saving the MultiFigure.On the other hand, though applying style customizations to the
MultiFigure
object will apply them to everyFigure
in the MultiFigure, customizations specified in the individualFigure
objects is prioritized over the MultiFigure’s customizations. This means that turning the grid on in the MultiFigure will turn it on for everyFigure
in the MultiFigure, but turning it off in an individualFigure
will override the MultiFigure’s setting and turn it off for thatFigure
only.
In short, the figure_style
chosen in the MultiFigure
constructor sets a base style for the MultiFigure as a whole. Calling the set_visual_params()
or the set_rc_params()
methods on the MultiFigure will personalize the chosen figure_style
for the MultiFigure. And calling these methods on the individual Figure
objects will alter the MultiFigure’s style for that Figure
only. Here is an example with customization of the axes edge colors:
# Create the curves
sine = gl.Curve.from_function(lambda x: np.sin(x), 0, 2 * np.pi, label="sine")
cosine = gl.Curve.from_function(lambda x: np.cos(x), 0, 2 * np.pi, label="cosine")
# Create the figures and add the elements
figure1 = gl.Figure(figure_style="dark") # this style is ignored when displaying the MultiFigure
figure1.add_elements(sine)
figure2 = gl.Figure()
figure2.add_elements(cosine)
# Create the MultiFigure and add the figures to it
# Use the "plain" style which has a black axes edge color
multifigure = gl.MultiFigure.from_row([figure1, figure2], size=(10, 4), figure_style="plain")
# Customize the axes edge color for all figures (but will be overridden for figure2)
# Note: order of these calls does not matter, figure2 will always override the MultiFigure
multifigure.set_visual_params(axes_edge_color="red")
figure2.set_visual_params(axes_edge_color="blue")
# Display the MultiFigure
# This will show the two figures side-by-side with the "plain" style, but
# the axes edge color will be red for figure1 and blue for figure2
multifigure.show()
# Display figure1 separately
# This will show figure1 with the "dark" style
# No axes edge color customization is applied
figure1.show()