Reputation: 309
I have a cohorted dataset (from 1 day to 365 days) that now I am representing like this in Seaborn. The blue line is the previous result, the orange is the current result and the bars are the delta in % between them:
However, I need to add the bars on the same plot that the lineplot with a secondary axis.
My expected output would be this for each plot of the Facetgrid:
A sample of the dataframe that I am using on wide format that I splited in two to separate the date from de delta and the pre y post results. I need it this way because of the cohorted data:
And this is the code I use to plot the first graph:
fig, ax1 = plt.subplots() # initializes figure and plots
ax2 = ax1.twinx() # applies twinx to ax2, which is the second y axis.
g = sns.FacetGrid(df_ads_long_st, col="m", hue="status", height=5, aspect=0.8)
g.map(sns.lineplot, "dx", "value_a", alpha=.7, ax = ax1)
g = sns.FacetGrid(df_ads_long_de, col="m", hue="status", height=5, aspect=0.8)
g.map(sns.barplot, "dx", "value_a", alpha=.7, ax = ax2)
# these lines add the annotations for the plot.
ax1.set_xlabel('DX')
ax1.set_ylabel('ARPU', color='b')
ax2.set_ylabel('Delta', color='r')
plt.show(); # shows the plot.
Is there any other day to do this?
Thanks!
Upvotes: 2
Views: 1661
Reputation: 1035
I had a similar requirement. The trick is to create your own function. In this function you create a twin axis.
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
def facetgrid_two_axes(data: pd.DataFrame, x_name: str, y1_name: str, y2_name: str, ylabel1: str, ylabel2: str):
ax1 = plt.gca()
sns.lineplot(data[x_name], data[y1_name], alpha=.7, ax=ax1)
ax1.set_ylabel(ylabel1)
ax2 = ax1.twinx()
sns.barplot(data[x_name], data[y2_name], alpha=.7, ax=ax2)
ax2.set_ylabel(ylabel2)
if __name__ == '__main__':
df_ads_long_st = pd.DataFrame(...) // Your data
g = sns.FacetGrid(df_ads_long_st, col="m", hue="status", height=5, aspect=0.8)
g.map_dataframe(facetgrid_two_axes, x_name="dx", y1_name="value_a", y2_name="value_a", alpha=.7,
ylabel1='Counts', ylabel2='Detection rates')
g.set_xlabels('x data')
plt.show()
A shortcoming I had, was that the ylabels are shown on every plot instead of only at the borders of the figure.
Upvotes: 2