Adrien
Adrien

Reputation: 433

Plotly: How to customize different bin widths for a plotly histogram?

I am trying to display an histogram with bins that have a different/customizable width. It seems that Plotly only allows to have a uniform bin width with xbins = dict(start , end, size).

For example, I would like for a set of data with integers between 1 and 10 display an histogram with bins representing the share of elements in [1,5[, in [5,7[ and [7,11[. With Matplotlib you can do it with an array representing the intervalls of the bins, but with plotly it seems thaht i must chose a uniform width.

By the way, I am not using Matplotlib since Plotly allows me to use features Matplotlib doesn't have.

Upvotes: 4

Views: 14063

Answers (2)

Nick S
Nick S

Reputation: 73

This doesn't answer the question exactly, but, imo, the widths of bins on a histogram should not have different widths. The fact that your intervals are unequal in size can be communicated with labels. Consider an alternative approach:

import pandas as pd
import plotly.express as px


# sample data
df = px.data.tips()

bins = [0, 15, 50]
hist_data = (
    pd.cut(df.total_bill, bins)
    .sort_values()  # to make the intervals appear in order
    .astype(str)  # our values are intervals, which plotly can't handle
)
px.histogram(hist_data)

enter image description here

This way you can even see that there's a value outside of your intervals.

Upvotes: 0

vestland
vestland

Reputation: 61094

If you're willing to handle the binning outside plotly, you can set the widths in a go.bar object using go.Bar(width=<widths>) to get this:

enter image description here

Complete code

import numpy as np
import plotly.express as px
import plotly.graph_objects as go

# sample data
df = px.data.tips()

# create bins
bins1 = [0, 15, 50]
counts, bins2 = np.histogram(df.total_bill, bins=bins1)
bins2 = 0.5 * (bins1[:-1] + bins2[1:])

# specify sensible widths
widths = []
for i, b1 in enumerate(bins1[1:]):
    widths.append(b1-bins2[i])

# plotly figure
fig = go.Figure(go.Bar(
    x=bins2,
    y=counts,
    width=widths # customize width here
))

fig.show()

Upvotes: 5

Related Questions