Search code examples
pythonmatplotlibmultiple-axes

matplotlib, place a transparent subplot on top of another subplot


My goal is to have a plot with a transparent background exactly on top of another plot, but with the y-axis on the other side. However, I do not know how to get the size right.

This code

plt.figure(1, figsize=(9, 3))
plt.subplot(1,1,1)  
plt.plot([1, 2], [3, 2], color='black')
ax2 = plt.axes([0, 0, 1, 1], facecolor='none')
ax2.yaxis.set_label_position("right")
ax2.yaxis.tick_right()
ax2.plot([1, 2], [3.1,2.1])

produces

enter image description here

So apparently, the size of the box needs to be set differently.

In case you are wondering why, here is the backdrop. My goal is to have a plot with 2 y-axes, one on the left and one on the right, where the left y-axis is interrupted and the right one is not. With interrupted I mean like this:

enter image description here

The figure is created with 2 subplots like this:

top_ratio = 1
bot_ratio = 4
gsdict={'height_ratios':[top_ratio, bot_ratio]}
f, (ax1, ax2) = plt.subplots(2, 1, sharex=True, gridspec_kw=gsdict)

However, if I now use twinx to get another y-axis, that new y-axis is only for one of the subplots, but I want it to go all the way from top to bottom. My idea is to create an additional axis with transparent background and add it on top.


Solution

  • You would want to create a new subplot at the same position as the existing ones. Because, by default, all subplots use the same subplot specifications, this is as easy ax3 = fig.add_subplot(111).

    import matplotlib.pyplot as plt
    
    gsdict={'height_ratios':[1, 4]}
    fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, gridspec_kw=gsdict)
    
    ax3 = fig.add_subplot(111, label="new subplot", facecolor="none")
    ax3.yaxis.set_label_position("right")
    
    ax3.tick_params(left=False, right=True, labelleft=False, labelright=True,
                    bottom=False, labelbottom=False)
    ax1.get_shared_x_axes().join(ax1,ax3)
    
    # just to see the effect, make spines green
    plt.setp(ax3.spines.values(), color="limegreen", linestyle=":")
    plt.show()
    

    enter image description here