# Building multiple plots on a single axes

I have seen many examples online of how to plot multiple results on a single set of axes but all of these follow a single set of instructions.

I am modularising my code, creating a set of global values, followed by a set of definitions and, finally, my main instructions; the reduced version being…


import matplotlib.pyplot as plt
import matplotlib.cbook as cbook

import numpy as np
import math

SIGMA = 5.67051e-5
PI    = math.pi
M_SUN = 1.989e33
L_SUN = 3.826e33
R_SUN = 6.9599e10
YEAR  = 3.15570e7

sa_sun = 4 * PI * math.pow(R_SUN, 2)
t_sun  = L_SUN / (sa_sun * SIGMA)

...SOME CODE HERE...

l_star = luminosity / L_SUN
r_star = np.power(radius / R_SUN, 2)

t_star = np.power((t_sun * l_star) / r_star, 0.25)

fig, axs = plt.subplots()

axs.loglog(t_star[:], l_star[:])
axs.invert_xaxis()

axs.set_title(r'Colour Magnitude (CM) Diagram')
axs.set_xlabel(r'Surface Temperature (Kelvin) - ${(\frac{t_{\odot} \times L_{\star}}{R_{\odot}})}^\frac{1}{4}$')
axs.set_ylabel(r'Luminosity (Solar Units) - $\frac{L_{\star}}{L_{\odot}}$')

plt.show()

if __name__ == "__main__":

CM_Graph(stellarData[:, 4],stellarData[:, 3])


This works perfectly to produce a single graph, where the data is taken from a single file (readData reads in the data from the file).
However, I intend on using multiple files and want the data to plot on the single axes; with the axes adjusting to match the data as a whole.

CM_Graph is going to be 1 of many graphs that the system will produce, hence the modularisation (and other reasons). I can see that I would create the subplots axs outside of the definitions and parse this in, but what then? Should the plt.show be in my main (thus, plotting all graphs). Do I call axs as GLOBAL within the CM_Graph, and would subsequent plots overwrite the earlier ones?

Sorry, so many questions.

An aside; what is fig for, on the line fig, axs = plt.subplots()? It is never used and I cannot find it mentioned in the documentation.

I have seen many examples online of how to plot multiple results on a
single set of axes but all of these follow a single set of
instructions.

Yeah. Probably deliberately simple.

I am modularising my code, creating a set of global values, followed by a set of definitions and, finally, my main instructions; the reduced version being…

def CM_Graph(luminosity, radius):
l_star = luminosity / L_SUN
r_star = np.power(radius / R_SUN, 2)
t_star = np.power((t_sun * l_star) / r_star, 0.25)
fig, axs = plt.subplots()
axs.loglog(t_star[:], l_star[:])
axs.invert_xaxis()
axs.set_title(r'Colour Magnitude (CM) Diagram')
axs.set_xlabel(r'Surface Temperature (Kelvin) - ${(\frac{t_{\odot} \times L_{\star}}{R_{\odot}})}^\frac{1}{4}$')
axs.set_ylabel(r'Luminosity (Solar Units) - $\frac{L_{\star}}{L_{\odot}}$')
plt.show()

if __name__ == "__main__":
CM_Graph(stellarData[:, 4],stellarData[:, 3])


This works perfectly to produce a single graph, where the data is taken from a single file (readData reads in the data from the file).
However, I intend on using multiple files and want the data to plot on the single axes; with the axes adjusting to match the data as a whole.

CM_Graph is going to be 1 of many graphs that the system will produce, hence the modularisation (and other reasons). I can see that I would create the subplots axs outside of the definitions and parse this in, but what then? Should the plt.show be in my main (thus, plotting all graphs). Do I call axs as GLOBAL within the CM_Graph, and would subsequent plots overwrite the earlier ones?

Yes, run plt.show() in your main code (or wherever the plots have all
been completed).

So you’ve plotted a log/log plot on the Axes you got from
subplots(). You can just do more plotting on the same Axes. Just do
them all before the plt.show().

An aside; what is fig for, on the line fig, axs = plt.subplots()? It is never used and I cannot find it mentioned in
the documentation.

Oh, it’s there! Somewhere… fig is a Figure and axs is a set of
Axes. A Figure is the whole diagram with potentially several plots
on it. The plt.subsplots() call returns you a tuple of the Figure
and its Axes. Sometimes you want one and sometimes the other (usualy
the Axes for the plotting stuff).

You can plot several eg lines on the same Axes pretty readily. They’ll
share the same y-axis.

To plot multiple things on the same x-axis but with distinct y-axis an Axes has a
twinx
method returning a new Axes using the same x-axis. Pyplot has a wrapper for it, too as
plt.twinx().

Exactly what you do depends on the outcome you want.

The docs for Axes at here:
https://matplotlib.org/stable/api/axes_api.html#matplotlib.axes.Axes
You’ll see that an Axes is contained in a Figure.

The docs for Figure are here:
https://matplotlib.org/stable/api/figure_api.html

The docs for plt.subplots are here:
https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.subplots.html?highlight=subplots#matplotlib.pyplot.subplots
and says it returns a Figure and an Axes, with links to the docs for
each. It’s a convenient wrapper for the Figure.subplots method, which
itself is a convenient wrapper for assembling a collection of Axes for
plots.

plotly is a kind of stateful convenience wrapper for the raw Figures
and Axes going on behind the scenes. When you do a plt.subplots() is
makes a “current” Figure and Axes and from then on you mostly don’t
need to talk about them. Subsequent plt.* calls use those “current”
Axes.

Cheers,
Cameron Simpson cs@cskk.id.au

···

On 26Oct2022 08:59, Gary Newport via Matplotlib nobody@discourse.matplotlib.org wrote:

1 Like

Thank you so much; all sorted"