5

I am making 2d histograms for some data with millions of data points. matplotlib.hist2d(x,y,bins,norm=LogNorm()) works well and produces a plot in about 5 seconds, but I like the marginal histograms of seaborn.jointplot(). How do I color the points in seaborn.jointplot() with log density of points like in the attached matplotlib.hist2d() figure? Using KDE takes way too long (I give up after about a minute or so), and I have lots of figures to create. So time to 'get' colors is a factor. Alternatively, how do I add marginal histograms to matplotlib.hist2d()?

plt.hist2d(x,y,100,norm=LogNorm(),cmap='jet')

enter image description here

sns.jointplot(x=x, y=y)

enter image description here

BML
  • 191
  • 2
  • 12

3 Answers3

9

There might be another direct way to get a color map in seaborn. I couldn't find any yet. Here is a hacky sample solution to get things done with some random data. As to your second problem, I would suggest to post a new question.

The trick is to first create a jointplot using seaborn and then hide the 2d-scatter and re-plot it using plt.hist2d

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

# some random data
x = np.random.normal(size=100000)
y = x * 3.5 + np.random.normal(size=100000)

ax1 = sns.jointplot(x=x, y=y)
ax1.ax_joint.cla()
plt.sca(ax1.ax_joint)

plt.hist2d(x, y, bins=(100, 100), cmap=cm.jet);

enter image description here

Sheldore
  • 37,862
  • 7
  • 57
  • 71
5

Here's an alternative, similar approach but sticking within seaborn:

import seaborn as sns
import numpy as np

x = np.random.normal(size=100)
y = x * 3.5 + np.random.normal(size=100)

sns.jointplot(x=x, y=y, kind='kde', cmap='hot_r', n_levels=60, fill=True)

enter image description here

busybear
  • 10,194
  • 1
  • 25
  • 42
  • Unfortunately kde is way too slow for millions of points, esp when there are dozens of figures to make. @Bazingaa's solution is best, see my comment below – BML Dec 31 '18 at 22:30
  • `cmap='jet'` gives me an error. Is it the right option? – a06e Nov 14 '21 at 18:02
  • They hilariously don't support jet anymore. There's a whole thing against jet that you can [google](https://www.reddit.com/r/Python/comments/8psk37/til_that_seaborn_refuses_to_use_the_jet_color/). You can just remove the [`cmap`](https://matplotlib.org/stable/tutorials/colors/colormaps.html) parameter or choose another colormap such as `magma` – busybear Nov 16 '21 at 15:04
2

Here's the final fig and code for it. Thanks to @Bazingaa for help.

def makesweetgraph(x=None, y=None, cmap='jet', ylab=None, xlab=None, bins=100, sets=sets, figsize=(5,4), snsbins=60):
    set1,set2 = sets
    ax1 = sns.jointplot(x=x, y=y,marginal_kws=dict(bins=snsbins))
    ax1.fig.set_size_inches(figsize[0], figsize[1])
    ax1.ax_joint.cla()
    plt.sca(ax1.ax_joint)
    plt.hist2d(x,y,bins,norm=LogNorm(),cmap=cmap)
    plt.title('%s vs %s (%.4f%% of loci)\n%s and %s' % (xlab,ylab,(len(x)/numsnps)*100,set1,set2),y=1.2,x=0.6)
    plt.ylabel(ylab,fontsize=12)
    plt.xlabel(xlab,fontsize=12)
    cbar_ax = ax1.fig.add_axes([1, 0.1, .03, .7])
    cb = plt.colorbar(cax=cbar_ax)
    cb.set_label(r'$\log_{10}$ density of points',fontsize=13)

enter image description here

BML
  • 191
  • 2
  • 12