pythonpandasmatplotlib

matplotlib multiple Y-axis pandas plot


I would like to do multiple Y axis plots.

This is some made up data below, how could I put Temperature its own Y axis, Pressure on its own Y axis, and then have both Value1 and Value2 on the same Y axis. I am trying to go for the same look and feel of this SO post answer.

I don't understand ax3 = ax.twinx() process; do I need to define an ax.twinx() for each separate Y axis plot I need?

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt



rows,cols = 8760,4
data = np.random.rand(rows,cols) 
tidx = pd.date_range('2019-01-01', periods=rows, freq='H') 
df = pd.DataFrame(data, columns=['Temperature','Value1','Pressure','Value2'], index=tidx)


# using subplots() function
fig, ax = plt.subplots(figsize=(25,8))
plt.title('Multy Y Plot')
 
ax2 = ax.twinx()    
ax3 = ax.twinx()    
ax4 = ax.twinx()

plot1, = ax.plot(df.index, df.Temperature)
plot2, = ax2.plot(df.index, df.Value1, color = 'r')
plot3, = ax3.plot(df.index, df.Pressure, color = 'g')
plot4, = ax4.plot(df.index, df.Value2, color = 'b')

ax.set_xlabel('Date')
ax.set_ylabel('Temperature')
ax2.set_ylabel('Value1')
ax3.set_ylabel('Pressure')
ax4.set_ylabel('Value2')


plt.legend([plot1,plot2,plot3,plot4],list(df.columns))

# defining display layout
plt.tight_layout()

# show plot
plt.show()

This will output everything jumbled up on the same side without separate Y axis for Pressure, Value1, and Value2.

enter image description here


Solution

  • You are adding 4 different plots in one, which is not helpful. I would recommend breaking it into 2 plots w/ shared x-axis "Date":

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    
    rows,cols = 8760,4
    data = np.random.rand(rows,cols) 
    tidx = pd.date_range('2019-01-01', periods=rows, freq='H') 
    df = pd.DataFrame(data, columns=['Temperature','Value1','Pressure','Value2'], index=tidx)
    fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(25,8))
    plt.title('Multy Y Plot')
     
    ax1b = ax1.twinx()    
    plot1a, = ax1.plot(df.index, df.Temperature)
    plot1b, = ax1b.plot(df.index, df.Pressure, color='r')
    
    ax1.set_ylabel('Temperature')
    ax1b.set_ylabel('Pressure')
    
    ax2b = ax2.twinx() 
    plot2a, = ax2.plot(df.index, df.Value1, color='k')
    plot2b, = ax2b.plot(df.index, df.Value2, color='g')
    
    ax2.set_xlabel('Date')
    ax2.set_ylabel('Value1')
    ax2b.set_ylabel('Value2')
    
    
    plt.legend([plot1a, plot1b, plot2a, plot2b], df.columns)
    
    # defining display layout
    plt.tight_layout()
    
    # show plot
    plt.show()
    

    resulting plots

    Here I have added in the first plot (on the top) Temperature and Pressure and on the second plot (on the bottom) Value 1 and Value 2. Normally, we add in the same plot things that make sense to compare on the same x-axis. Pressure and Temperature is a valid combination that is why I combined those two together. But you can do as you wish.