pandasmatplotlibz-order

How to change the order of these plots using zorder?


I'm trying to get a line plot to be over the bar plot. But no matter what I do to change the zorder, it seems like it keeps the bar on top of the line. Nothing I do to try to change zorder seems to work. Sometimes the bar plot just doesn't show up if zorder is <= 0.

import pandas as pd
import matplotlib.pyplot as plt

def tail_plot(tail):

    plt.figure()

    #line plot
    ax1 = incidence[incidence['actual_inc'] != 0].tail(tail).plot(x='date', y=['R_t', 'upper 95% CI', 'lower 95% CI'], color = ['b', '#808080', '#808080'])
    ax1.set_zorder(2)

    ax2 = ax1.twinx()

    inc = incidence[incidence['actual_inc'] != 0]['actual_inc'].tail(tail).values

    dates = incidence[incidence['actual_inc'] != 0]['date'].tail(tail).values

    #bar plot
    ax2.bar(dates, inc, color ='red', zorder=1)  
    ax2.set_zorder(1)

Keeps giving me this:

enter image description here


Solution

  • The problem with the approach in the post is that ax1 has a white background which totally occludes the plot of ax2. To solve this, the background color can be set to 'none'.

    Note that the plt.figure() in the example code of the post creates an empty plot because the pandas plot creates its own new figure (as no ax is given explicitly).

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    
    df = pd.DataFrame({f'curve {i}': 20 + np.random.normal(.1, .5, 30).cumsum() for i in range(1, 6)})
    
    # line plot
    ax1 = df.plot()
    ax1.set_zorder(2)
    ax1.set_facecolor('none')
    ax2 = ax1.twinx()
    
    # bar plot
    x = np.arange(30)
    ax2.bar(x, np.random.randint(7 + x, 2 * x + 10), color='red', zorder=1)
    ax2.set_zorder(1)
    plt.show()
    

    demo plot