Python plot different variables on same y axis

Viewed 688

I want to visualize many parameters over time. Basically, I want to plot datetime on x-axis, different parameters on y-axis.

My code:

df = 
index                     y1        y2         y3
2021-03-14 08:38:22   34.660422  6.278744  443.253277
2021-03-14 08:39:11   34.853815  6.267421  446.127032
2021-03-14 08:40:01   34.966101  6.338569  446.868933
2021-03-14 08:41:13   34.687784  6.339623  454.871855
2021-03-14 10:42:56  403.837103  9.091500  847.931740

# plot
plt.plot(df.index,df['y1'],'o')
plt.plot(df.index,df['y2'],'o')
plt.plot(df.index,df['y3'],'o')
plt.show()

It outputs the plot. The problem is, y1 data dominates y2 and we cannot clearly see the second column trend. How do I address this?

1 Answers

Option 1. You can plot y1 and y2 on different y axes so that the scale of one does not overwhelm the other one:

fig = plt.figure(figsize=(8,6))
ax1 = fig.add_subplot()
ax2 = ax1.twinx()
ax1.set_ylabel("y1 data")
ax2.set_ylabel("y2 data")
ax1.plot(df.index,df.y1, color = 'red', label = 'y1')
ax2.plot(df.index, df.y2, color = 'blue', label = 'y2')
fig.autofmt_xdate()

ax1.legend()
ax2.legend(loc = 'upper right')
plt.show()

enter image description here

If you have more than two data columns with different orders of magnitude as in your updated question, you have two options:

Option 2. Create multiple subplots. By vertically stacking them, you can re-enforce the fact that they use the same x-axis.

fig,axes = plt.subplots(len(df.columns),1)
for i, ax in enumerate(axes):
    ax.set_ylabel(df.columns[i])
    ax.plot(df.index,df.iloc[:,i], c = (random.random(),random.random(),random.random()))
fig.autofmt_xdate()
plt.suptitle('Stacked Subplots')
plt.show()

enter image description here

Option 3. You can scale all dataframe columns to the same order of magnitude, plot them is the same plot and include the scale factors in the legend.

def order_of_mag(num):
    return math.floor(math.log10(num))

min_order_of_mag = order_of_mag(min(df.min()))
column_scale_factors = [10 ** (order_of_mag(v) - min_order_of_mag) for v in df.min()]

fig,ax = plt.subplots()
for i in range(len(df.columns)):
    ax.plot(df.index, df[df.columns[i]]/column_scale_factors[i], label = f'{df.columns[i]} data x {column_scale_factors[i]}')
fig.autofmt_xdate()
plt.xlabel('Date')
plt.legend()
plt.title('Scaled Y Data')
plt.show()

enter image description here

Related