Search code examples
pythonmatplotlibz-ordertwinx

How do you controle zorder across twinx in matplotlib?


I'm trying to control the zorder of different plots across twinx axes. How can I get the blue noisy plots to appear in the background and the orange smoothed plots to appear in the foreground in this plot?

from matplotlib import pyplot as plt
import numpy as np
from  scipy.signal import savgol_filter

random = np.random.RandomState(0)
x1 = np.linspace(-10,10,500)**3 + random.normal(0, 100, size=500)
x2 = np.linspace(-10,10,500)**2 + random.normal(0, 100, size=500)

fig,ax1 = plt.subplots()
ax1.plot(x1, zorder=0)
ax1.plot(savgol_filter(x1,99,2), zorder=1)
ax2 = ax1.twinx()
ax2.plot(x2, zorder=0)
ax2.plot(savgol_filter(x2,99,2), zorder=1)
plt.show()

Solution

  • Similar to this thread, though not ideal, this is an approach using twiny along with twinx.

    # set up plots
    fig, ax1 = plt.subplots()
    
    ax2 = ax1.twinx()
    ax3 = ax1.twiny()
    ax4 = ax2.twiny()
    
    # background
    ax1.plot(x1)
    ax2.plot(x2)
    
    # smoothed
    ax3.plot(savgol_filter(x1,99,2), c='orange')
    ax4.plot(savgol_filter(x2,99,2), c='orange')
    
    # turn off extra ticks and labels
    ax3.tick_params(axis='x', which='both', bottom=False, top=False)
    ax4.tick_params(axis='x', which='both', bottom=False, top=False)
    ax3.set_xticklabels([])
    ax4.set_xticklabels([])
    
    # fix zorder
    ax1.set_zorder(1)
    ax2.set_zorder(2)
    ax3.set_zorder(3)
    ax4.set_zorder(4)
    
    plt.show()
    

    Output:

    enter image description here