19

I'm trying to create a loglog plot with a KDE and histogram associated with each axis using a seaborn JointGrid object. This gets me pretty close, but the histogram bins do not translate well into logspace. Is there a way to do this easily without having to recreate the marginal axes?

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

data = sns.load_dataset('tips')
g = sns.JointGrid('total_bill', 'tip', data)
g.plot_marginals(sns.distplot, hist=True, kde=True, color='blue')
g.plot_joint(plt.scatter, color='black', edgecolor='black')
ax = g.ax_joint
ax.set_xscale('log')
ax.set_yscale('log')
g.ax_marg_x.set_xscale('log')
g.ax_marg_y.set_yscale('log')

Output of plot

Koppology
  • 262
  • 1
  • 2
  • 6
  • I don't think you'll get any closer than what you have now. This is something that I think `jointplot` should handle better itself, but I've been wary to add it because I'm not sure exactly what people will expect to make the most sense. Can you say what you would prefer the histograms to look like? Constant-width bars in log space? – mwaskom Sep 26 '14 at 14:45
  • 1
    Yep -- constant-width bars would be fantastic. I know how to do this using ax.hist and np.logspace by hand, but for use with seaborn I think I'm going to go ahead and log the data in the DataFrame and then apply 10^x to the axis labels afterwards as a workaround. As a side note, I'm confused as to why just setting ax = g.ax_joint ax.set_xscale('log') ax.set_yscale('log') doesn't automatically set the marginal axes? Thanks for the response, it's a great package! – Koppology Sep 26 '14 at 15:54
  • That is surprising. Those axes are shared when seaborn sets up the `JointGrid`, so it suggests an inconsistency in matplotlib. – mwaskom Sep 26 '14 at 17:15

1 Answers1

20

For log histograms I find generally useful to set your own bins with np.logspace().

mybins=np.logspace(0,np.log(100),100)

Then just set bins= in _marginals

data = sns.load_dataset('tips')
g = sns.JointGrid('total_bill', 'tip', data,xlim=[1,100],ylim=[0.01,100])
g.plot_marginals(sns.distplot, hist=True, kde=True, color='blue',bins=mybins)
g.plot_joint(plt.scatter, color='black', edgecolor='black')
ax = g.ax_joint
ax.set_xscale('log')
ax.set_yscale('log')
g.ax_marg_x.set_xscale('log')
g.ax_marg_y.set_yscale('log')

enter image description here

tsherwen
  • 1,076
  • 16
  • 21
lalmei
  • 379
  • 3
  • 6
  • 1
    Newer versions of Seaborn allow to do it without calling logspace like this: `g.plot_marginals(sns.histplot, log_scale=True, bins=100, kde=True)` – roman May 17 '21 at 11:54