'Facetgrid Formatting and sorting each graph

Below is the code I've created to run the facetgrid graph. As you can see, merged1 is the first dataframe and merged2 is the second dataframe I am iterating on. There are two things I am trying to accomplish.

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

# initialize list of lists
data = [['tom', 5000, 200,5, 900 ], ['tom', 7000, 500,5, 900 ], ['nick', 7000,300,4 ,4000], ['nick', 8000,200,4 ,4000], ['juli',9000,300,2, 8000,], ['juli',15000,300,2, 8000,], ['TEST',10000,300,3,8000], ['TEST',8000,800,3,8000],['hang', 5000, 330,1.6,5000 ], ['hang', 1000, 330,5,5000 ]]
 
# Create the pandas DataFrame
df = pd.DataFrame(data, columns = ['Donor', 'Days-post-ARV','CD4', 'VL','Days Post-COLDATE'])

#creating two separate datframes
merged1=df.drop(columns=['CD4'])
merged2=df.drop(columns=['VL'])

#function for reference vertical line 
def vertical_mean_line(x, **kwargs):
    plt.axvline(x.mean(), **kwargs)  

#for the first dataframe    
g = sns.relplot(data=merged1, x='Days-post-ARV', y='VL', col='Donor',col_wrap=3, kind="line", height=4, aspect=1.5,
                color='b')
#for the vertical line
g.map(vertical_mean_line, 'Days Post-COLDATE',ls="--",color='g')

#for the second dataframe
for patid, ax in g.axes_dict.items():  # axes_dict is new in seaborn 0.11.2
    ax1 = ax.twinx()
    sns.lineplot(data=merged2[merged2['Donor'] == patid], x='Days-post-ARV', y='CD4', color='r', ax=ax1)
    ax1.set_ylim(0,1200)

g.add_legend()   
g.tight_layout()

  1. What's the best way to sort the graph? I'd like to switch the order of the second and third graph.
  2. When plotting, the Y-axis between each graph gets merged and seeing only the 'CD4' between each graph, but there is the first Y-axis label 'VL' that should be showing up. How can I do this?enter image description here


Solution 1:[1]

Well, the test data and the original test code give:

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

# initialize list of lists
data = [['tom', 5000, 200, 5, 900], ['tom', 7000, 500, 5, 900], ['nick', 7000, 300, 4, 4000], ['nick', 8000, 200, 4, 4000], ['juli', 9000, 300, 2, 8000, ], ['juli', 15000, 300, 2, 8000, ], ['TEST', 10000, 300, 3, 8000], ['TEST', 8000, 800, 3, 8000], ['hang', 5000, 330, 1.6, 5000], ['hang', 1000, 330, 5, 5000]]
# Create the pandas DataFrame
df = pd.DataFrame(data, columns=['Donor', 'Days-post-ARV', 'CD4', 'VL', 'Days Post-COLDATE'])

# creating two separate datframes
merged1 = df
merged2 = df

# function for reference vertical line
def vertical_mean_line(x, **kwargs):
     plt.axvline(merged1[x].mean(), **kwargs)

# for the first dataframe
g = sns.relplot(data=merged1, x='Days-post-ARV', y='VL', col='Donor', col_wrap=3, kind="line", height=4, aspect=1.5,
                color='b')
# for the vertical line
g.map(vertical_mean_line, x='Days-post-ARV', ls="--", color='g')

# for the second dataframe
for patid, ax in g.axes_dict.items():  # axes_dict is new in seaborn 0.11.2
     ax1 = ax.twinx()
     sns.lineplot(data=merged2[merged2['Donor'] == patid], x='Days-post-ARV', y='CD4', color='r', ax=ax1)
     ax1.set_ylim(0, 1200)
g.add_legend()
g.tight_layout()
plt.show()

You'll notice the order of the subplots is the same as the order the donors appear in the dataframe: ['tom', 'nick', 'juli', 'TEST', 'hang'].

sns.relplot original

It seems Seaborn not only removes the left y label, it also sets it invisible. You'll need to set it visible again. Note that changes to ax influence the left ticks and left labels, while changes to ax1 influence the ticks and the labels at the right of the subplots.

Changing the code to add a new col_order. And adding ax.set_ylabel('VL', visible=True):


# for the first dataframe, NEW col_order
g = sns.relplot(data=merged1, x='Days-post-ARV', y='VL', col='Donor', col_wrap=3, kind="line", height=4, aspect=1.5,
                color='b', col_order=['tom', 'juli', 'nick', 'TEST', 'hang'])
# for the vertical line
g.map(vertical_mean_line, x='Days-post-ARV', ls="--", color='g')

# for the second dataframe
for patid, ax in g.axes_dict.items():  # axes_dict is new in seaborn 0.11.2
     ax1 = ax.twinx()
     sns.lineplot(data=merged2[merged2['Donor'] == patid], x='Days-post-ARV', y='CD4', color='r', ax=ax1)
     ax1.set_ylim(0, 1200)
     ax.set_ylabel('VL', visible=True) # ADDED

g.add_legend()
g.tight_layout()
plt.show()

new sns.relplot

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 JohanC