Porada Kev
Porada Kev

Reputation: 513

Python. Use two y axis for line and bar plots on Seaborn Facetgrid

Updated question and code! Probably, the tips dataset is not the best example to use, however my issue is reproduced in it, i.e. we see that both point and bar plots share the same Y

I need to combine line and bar plots on one chart. To do this I used seaborn and the following code:

tips = sns.load_dataset('tips')

g = sns.FacetGrid(tips, hue='sex', col='sex', size=4, aspect=2.1, sharey=False, sharex=False)

g = g.map(sns.pointplot, 'day', 'tip', ci=0)
g = g.map(sns.barplot, 'day', 'total_bill', ci=0)

g.set_xticklabels(rotation=45, fontsize=9)
g.set_xticklabels(rotation=45, fontsize=9)

plt.show()

Here is the result: enter image description here

Everything is okay except the fact that one Y axis is used for both bars and lines on each facetgrid object. I am new to seaborn and currently cannot find a solution. Tried to add "sharey=False" to this line of code

> `g.map(sns.pointplot, 'date', 'worthusdcount')`

however it didn't help.

Any solutions on how to add second Y axis would be appreciated

Upvotes: 3

Views: 5518

Answers (1)

filup
filup

Reputation: 195

Here's an example where you apply a custom mapping function to the dataframe of interest. Within the function, you can call plt.gca() to get the current axis at the facet being currently plotted in FacetGrid. Once you have the axis, twinx() can be called just like you would in plain old matplotlib plotting.

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

def facetgrid_two_axes(*args, **kwargs):
    data = kwargs.pop('data')
    dual_axis = kwargs.pop('dual_axis')
    alpha = kwargs.pop('alpha', 0.2)
    kwargs.pop('color')
    ax = plt.gca()
    if dual_axis:
        ax2 = ax.twinx()
        ax2.set_ylabel('Second Axis!')

    ax.plot(data['x'],data['y1'], **kwargs, color='red',alpha=alpha)
    if dual_axis:
        ax2.bar(df['x'],df['y2'], **kwargs, color='blue',alpha=alpha)


df = pd.DataFrame()
df['x'] = np.arange(1,5,1)
df['y1'] = 1 / df['x']
df['y2'] = df['x'] * 100
df['facet'] = 'foo'
df2 = df.copy()
df2['facet'] = 'bar'

df3 = pd.concat([df,df2])
win_plot = sns.FacetGrid(df3, col='facet', size=6)
(win_plot.map_dataframe(facetgrid_two_axes, dual_axis=True)
         .set_axis_labels("X", "First Y-axis"))
plt.show()

This isn't the prettiest plot as you might want to adjust the presence of the second y-axis' label, the spacing between plots, etc. but the code suffices to show how to plot two series of differing magnitudes within FacetGrids.

seaborn_double_y_axis

Upvotes: 3

Related Questions