1

I am trying to create a figure with three subplots. The bottom left subplot is supposed to be a 2D histogram with projections on the top and right sides. The 2D histogram is supposed to be square (hence, the scaleanchor=x3) and I would like to use constrain='domain' to keep the 2D histogram tidy.

With the code shown below, the right projection has a far greater spacing than the top projection (see image). They are supposed to have the same spacings. How can I fix this?

This is my MWE:

import plotly.graph_objs as go from plotly.subplots import make_subplots fig = make_subplots( rows=2, cols=2, shared_xaxes=True, shared_yaxes=True, column_widths=[0.8, 0.2], row_heights=[0.2, 0.8], horizontal_spacing=0.02, vertical_spacing=0.02, ) fig.add_trace(go.Bar(), row=1, col=1) fig.add_trace(go.Bar(), row=2, col=2) fig.add_trace(go.Heatmap(), row=2, col=1) fig.update_layout( xaxis3=dict(range=[0, 1], constrain='domain'), yaxis3=dict(range=[0, 1], constrain='domain', scaleanchor='x3'), ) fig.show() 

Example output using randomly generated data:

enter image description here

1 Answer 1

1

Note you can use a 2d-histogram trace (instead of a heatmap), and two histogram traces (instead of bar traces).

Also, Plotly Express provides a density_heatmap function for plotting 2D-Histograms / Density Heatmaps, which are computed by grouping a set of points specified by their x and y coordinates into bins, and applying an aggregation function such as count or sum to compute the color of the tile representing the bin.

Marginal plots can be added to visualize the 1-dimensional distributions of the two variables using marginal_x and marginal_y parameters, allowed values are histogram, violin, box and rug.

So you can create the subplots and the 3 traces in one call :

import plotly.express as px df = px.data.tips() fig = px.density_heatmap(df, x="total_bill", y="tip", marginal_x="histogram", marginal_y="histogram") 

Now, for the spacing issue, the simplest imho would be to set the figure width and height to a square ratio, eg. :

fig.update_layout(width=800, height=800) 
Sign up to request clarification or add additional context in comments.

3 Comments

Hi, thank you for your answer and the tip regarding the marginal_x and marginal_y parameters. Sadly, setting the figure width and height to square ratio doesn't work for me, because I want to put that plot into a dash app, where the size of the figure can depend on e.g. the screen size and so on. Is there maybe a different way to fix that?
The thing is if the 2D histogram is a square and the whole figure is not, then you will necessarily have spaces somewhere, the constrain parameter will only affects how the gaps are filled. But, if you just use the px.density_heatmap() function (no additional layout parameters), the spaces should be spread evenly around the 2d-histogram (left+right instead of right only).
Yeah, that makes sense. However, I need the heatmap to be a square, so just not using any layout parameters doesn't work for me with neither px.density_heatmap() nor make_subplots(). I am aware that there will spaces, but I want them to be on the outside and not in the space between subplots. The plot doesn't have to fill the entire area.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.