0

I am plotting multiple sets of data on separate subplots, showing the difference between plotting a function on a linear vs a logarithmic x-axis. Since the subplot labels and x-axes remain unchanged, I am plotting the data on each subplot, saving the figure, removing the lines, and repeating (taking inspiration from this answer). I am able to autoscale the y-axis for each subplot based on the data in the corresponding subplot (thanks to this answer):

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec

fig = plt.figure(figsize=(12,6))
gs = GridSpec(1, 2, figure=fig, width_ratios=[1, 1])
ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])

ax1.set_xlabel(r"$x$")
ax1.set_yscale("log")
ax1.set_ylabel(r"$f(x)$")

ax2.set_xscale("log")
ax2.set_xlabel(r"$x$")
ax2.set_yscale("log")
ax2.set_ylabel(r"$f(x)$")

for i in range(whatever): # looping over all sets of data
    ax1.plot(x_linear[i], y_linear[i])
    ax1.relim()
    ax1.autoscale(axis="y")

    ax2.plot(x_log[i], y_log[i])
    ax2.relim()
    ax2.autoscale(axis="y")

    fig.savefig("%s.png" % i)
    for line in ax1.get_lines():
        line.remove()
    for line in ax2.get_lines():
        line.remove()

However, I would like to autoscale the y-axis for both subplots based on all of the data, such that both y-axes are the same. For example, this is the sort of figure I am currently making, and this is the sort of figure I would like to make. I have considered two methods so far:

  • plotting both sets of data in each subplot, rescaling each y-axis, and then removing the necessary lines from each subplot
  • plotting both sets of data in each subplot and make the necessary lines invisible (alpha=0.)

While these would work, I have a lot of data and a lot of plots to make, and am just wondering if there is another tidier and more efficient way of going about this that avoids unnecessary plotting. Any help is appreciated.

campioru
  • 1
  • 2

1 Answers1

0

You can manually sharey between the axes, but its usually easier to do it at startup

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12,6), sharey=True,
                               gridspec_kw={'width_ratios': [1, 1]})

See https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.subplots.html

Jody Klymak
  • 4,979
  • 2
  • 15
  • 31
  • I don't think this would work, as when I remove the lines (```line.remove()```), the y-axis for each subplot remains unchanged unless I explicitly re-scale it (```ax.relim()```). I want both y-axes to re-scale to the same scale, however if I was to simply share y-axes using ```sharey=True```, I would need to know which subplot needs to be scaled further than autoscaling, which I do not know as I have lots of data. – campioru Aug 26 '22 at 20:10
  • I see. What you want isn't hard - just get the new limits and then manually set to the extrema before you draw - but it would be nice if you concocted a self-contained minimal example to test with. – Jody Klymak Aug 26 '22 at 20:20
  • 1
    Are you suggesting to autoscale each subplot and then obtain each pair of limits using ```ax.get_ylim()``` and then set each subplot's limits to the minimum and maximum of these? That could indeed be more efficient than my suggestions – campioru Aug 26 '22 at 20:28
  • Yep, thats what I meant... – Jody Klymak Aug 26 '22 at 21:27