Home > database >  How to use secondary Y-axis for multiple subplots in seaborn
How to use secondary Y-axis for multiple subplots in seaborn

Time:01-17

I have two data frame which has multiple columns. I have turned DataFrame into long-form using pd.wide_to_long

df1 = pd.wide_to_long(df_1.reset_index(), ['dvr','r'], i='index', j='Sample ID').reset_index()
df2 = pd.wide_to_long(df_2.reset_index(), ['dvlnr','r'], i='index', j='Sample ID').reset_index()

I want to create subplots and am inclined to use seaborn due to its elegant formatting features. Here is my code to generate a subplot with secondary Y-Axis.

ax= sns.relplot(data=df1, x='r', y='dvlnr', col='Sample ID',  col_wrap=2, kind="line", height=4, aspect=1.5)
ax1 = plt.twinx()
ax1= sns.relplot(data=df2, x='r', y='dvr', ax=ax, col='Sample ID',  col_wrap=2, kind="line", height=4, aspect=1.5) 

But I always get ValueError: Could not interpret value 'dvr' for parameter 'y'

I have checked a few examples combining sns.relplot via ax.twinx()

If the ranges of the y-data are similar enough, you can merge the dataframes and plot everything in one go using hue=. (This approach would also work with more dataframes.)

  • a new column (e.g. 'source') needs to be added to indicate the original dataframe
  • corresponding columns in both dataframes need the same name

Here is some example code:

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

df1 = pd.DataFrame({'r1': np.random.randint(1, 31, 200),
                    'dvr1': np.random.uniform(100, 1000, 200),
                    'Sample ID': np.random.randint(1, 5, 200)})
df2 = pd.DataFrame({'r1': np.random.randint(1, 31, 300),
                    'dvlnr1': np.random.uniform(300, 1200, 300),
                    'Sample ID': np.random.randint(1, 5, 300)})

# add an extra column to tell to which df the data belongs
df1['source'] = 'dvr'
# the corresponding columns in both df need to have the same name for the merge
df2 = df2.rename(columns={'dvlnr1': 'dvr1'})
df2['source'] = 'dvrnr'
df_merged = pd.concat([df1, df2]).reset_index()

g = sns.relplot(data=df_merged, x='r1', y='dvr1', hue='source', col='Sample ID', col_wrap=2,
                kind="line", height=4, aspect=1.5, palette='turbo')
plt.subplots_adjust(bottom=0.06, left=0.06)  # plt.tight_layout() doesn't work due to legend
plt.show()

sns.relplot with hue on newly created column for merged dfs

  •  Tags:  
  • Related