-1

I am familiar to using twinx() to share an axis's x-axis with another subplot:

fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.plot(xdata1, ydata1)
ax2.plot(xdata2, ydata2)

This makes the y=0 axis line up between ax1 and ax2, but the axes are still on separate subplots so they each get their own autoscaling to match whatever is plotted on them as normal. However, I have a situation where I need to create separate axes ax1 and ax2 on the different subplots, but with a specified offset between their x-axes - i.e. ax1's y=y0 needs to line up with ax2's y=0, for some nonzero offset y0, like this:

enter image description here

This post appears to be close to what I am after, but not quite the same. That example uses a secondary y-axis with a function relating its values to the primary y-axis. However, I need a separate subplot entirely with its own scaling just like twinx() gives me.

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
PGmath
  • 381
  • 3
  • 16
  • please provide a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) of what you're trying to do! – raphael Jun 03 '23 at 16:21

1 Answers1

0

all you need to do is to create a new subplot manually and set its position relative to the first subplot. Then you can share the x axis via ax.sharex(...) and you're good to go

This should do the job:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10*np.pi, 1000)
ydata1 = np.exp(x/10)
ydata2 = np.sin(x)


fig, ax1 = plt.subplots()
fig.subplots_adjust(top=0.8)

ax2 = fig.add_subplot() # create a new subplot
pos = list(ax1.get_position().bounds) # get the position of the first subplot
pos[1] += 0.15  # shift the y-position of the subplot... pos = (x0, y0, width, height)
ax2.set_position(pos) # set the new position
ax2.sharex(ax1)       # share x axis with first subplot
ax2.patch.set_visible(False) # hide the background patch
ax2.tick_params(left=False, labelleft=False, # put ticks and labels on the right axis
                right=True, labelright=True)

ax1.plot(x, ydata1, "r-")
ax2.plot(x, ydata2, "b-")
raphael
  • 2,159
  • 17
  • 20