Working with multiple plots

Figures

GRUtils stores the data generated in the creation of plots in objects of the type Figure. There is a global "current figure" that is silently used by all the basic functions to create, modify and save plots. New figures can be created with the Figure constructor, which in its simplest form is just a call to Figure().

As all Julia objects, figures can be assigned to variables, a useful resource to work with different figures. The current figure can be retrieved with the function gcf() – standing for "get current figure", and is also returned by plotting functions like plot. On the other hand, a figure that is stored in the variable fig can be made the current figure by gcf(fig).

Most functions to work with plots in GRUtils have methods or variants that allow to specify what figure will be used. For instance, all plotting functions (e.g. plot, scatter, histogram, etc.) have "in-place" versions whose name end with an exclamation mark (i.e. plot!, scatter!, histogram!...). The first argument of those functions is the Figure object where the plot will be created. Let's see an example:

plot(x, y)       # creates a plot in the current figure
fig = gcf()      # assigns the current figure to `fig`
fig2 = Figure()  # now `gcf()` will refer to `fig2`
plot(x, z)       # this is plotted `fig2`
plot!(fig, x, z) # draws the same plot in `fig`
gcf(fig)         # now `gcf()` will refer to `fig` again

To save a particular figure in an image file, give the variable that contains the figure as second argument to the function savefig, i.e. savefig(filename, fig).

Some programming environments may provide only one graphic device, but you can still work with various figures, although only one can be seen at the same time. To show again a figure that might have been replaced by another on the display, you just have to "call" it, or explicitly use the display function on it, like this:

# `fìg` is a figure with a plot to be shown
fig
display(fig)  # Normally the same as just calling `fig`

This action also comes in handy to update the visualization of a figure that might have been modified after its creation.

On the other hand, show(fig) will normally show the textual representation of the figure on the screen.

Subplots

A figure can contain one or various plots, arranged in a flexible layout. The individual plots are stored in objects of the type PlotObject; all the plots of a figure referred to by the variable fig are collected in the array fig.plots. Normally, plotting operations are applied to the last "subplot", which can be retrieved by the function currentplot(::Figure). Without arguments, that function returns the current plot of the current figure.

The function subplot can be used to split the current figure into a grid of plots, and define a "subplot" that covers one or more cells of that grid.

Subplots can be created for specific figures with the "in-place" function subplot!, which differs from subplot in that it takes the figure as first argument.

The functions that set the Plot attributes also have in-place versions (e.g. title!, legend!, etc.), whose first argument is the figure or the specific plot whose attributes are meant to be modified. For instance:

# Example data
x = 1:20
y = randn(20)
z = exp.(y) .+ randn(20)
leftplot = subplot(1,2,1)
plot(x, y)     # Line plot on the left hand side
rightplot = subplot(1,2,2)
scatter(y, z)  # Scatter plot to the right hand side

fig = gcf()
title!(fig, "Nice plot")         # Same as `title("Nice plot")`
title!(leftplot, "First plot")  # Set the title of the first plot
fig   # The function `title!` does not update the visualization