2D histograms in plotly

2D histograms in plotly with density_heatmap

2D histograms, also known as density heatmaps, are the generalization of histograms for two variables that consist on dividing the data in bins and applying a function (generally the count of observations) to compute the color to be used for each bin. When using plotly, you can create this chart with the density_heatmap function from plotly express.

You will need to pass as input two numerical variables to x and y. You can also specify a title and the labels if needed, or the axis range with range_x and/or range_y.

import plotly.express as px
import numpy as np

# Sample data
np.random.seed(2)
x = np.random.normal(size = 500)
y = x + np.random.normal(size = 500) ** 2

fig = px.density_heatmap(x = x, y = y,
                         title = 'Density heatmap',
                         labels = {'x': 'X-axis', 'y': 'Y-axis'})

fig.show()

Number of bins

The nbinsx and nbinsy arguments control the number of bins along the X and Y-axis, respectively. You will need to specify a positive integer for one or both axis if desired.

import plotly.express as px
import numpy as np

# Sample data
np.random.seed(2)
x = np.random.normal(size = 500)
y = x + np.random.normal(size = 500) ** 2

fig = px.density_heatmap(x = x, y = y,
                         nbinsx = 10, nbinsy = 10)

fig.show()

Aggregation functions

The histfunc argument controls the function used for summarizing the values passed to z. This is, the function used to calculate the corresponding value for each bin. Possible functions are 'count' (default), 'sum', 'avg', 'min' and 'max'.

import plotly.express as px
import numpy as np

# Sample data
np.random.seed(2)
x = np.random.normal(size = 500)
y = x + np.random.normal(size = 500) ** 2
z = x + np.random.normal(size = 500)

fig = px.density_heatmap(x = x, y = y, z = z, histfunc = 'avg')

fig.show()

Texts

The density_heatmap function provides an argument named text_auto which can be used to show text inside each bin displaying the count, sum, average, minimum or maximum values, depending on the aggregation function used.

import plotly.express as px
import numpy as np

# Sample data
np.random.seed(2)
x = np.random.normal(size = 500)
y = x + np.random.normal(size = 500) ** 2

fig = px.density_heatmap(x = x, y = y, text_auto = True)

fig.show()

Color palette

The default color palette used for the bins can be customized with color_continuous_scale. Note that you can also modify the midpoint with color_continuous_midpoint or the range of the colors passing a pair of numbers to range_color. If you want to know the names of the available plotly color palettes import plotly express as px and then type px.colors.named_colorscales().

import plotly.express as px
import numpy as np

# Sample data
np.random.seed(2)
x = np.random.normal(size = 500)
y = x + np.random.normal(size = 500) ** 2

fig = px.density_heatmap(x = x, y = y, color_continuous_scale = 'gnbu')

fig.show()

2d histograms with marginal plots

Making use of the marginal_x and marginal_y arguments you can add marginal plots to the plotly 2D histograms. Possible options are 'rug' for rug plots, 'box' for box plots, 'violin' for violin plots and 'histogram' for histograms. Recall that you don’t need to set both marginal plots at the same time and otherwise you can set a different marginal plot for each axis.

Marginal rug plots

import plotly.express as px
import numpy as np

# Sample data
np.random.seed(2)
x = np.random.normal(size = 500)
y = x + np.random.normal(size = 500) ** 2

fig = px.density_heatmap(x = x, y = y,
                         marginal_x = 'rug', marginal_y = 'rug')

fig.show()

Marginal box plots

import plotly.express as px
import numpy as np

# Sample data
np.random.seed(2)
x = np.random.normal(size = 500)
y = x + np.random.normal(size = 500) ** 2

fig = px.density_heatmap(x = x, y = y,
                         marginal_x = 'box', marginal_y = 'box')

fig.show()

Marginal violin plots

import plotly.express as px
import numpy as np

# Sample data
np.random.seed(2)
x = np.random.normal(size = 500)
y = x + np.random.normal(size = 500) ** 2

fig = px.density_heatmap(x = x, y = y,
                         marginal_x = 'violin', marginal_y = 'violin')

fig.show()

Marginal histograms

import plotly.express as px
import numpy as np

# Sample data
np.random.seed(2)
x = np.random.normal(size = 500)
y = x + np.random.normal(size = 500) ** 2

fig = px.density_heatmap(x = x, y = y,
                         marginal_x = 'histogram', marginal_y = 'histogram')

fig.show()
Storytelling with Data

A Data Visualization Guide for Business Professionals

Buy on Amazon

See also