Bargap 0 + small bar width. Possible?

Hi,

What I want to do:
I have a div in Dash that is of fixed size. In it is displayed a Graph which is longer than the parent div. So I added an overflow y option to the parent div. Now, I would like for the Graph (bar chart) to be as “compressed” as possible. Meaning small bar width and low bargap. The reason for that is that I don’t want the user having to scroll for just 4-5 elements.

Here is an example from the plotly page which I modified slightly:

import plotly.graph_objects as go

years = [1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
         2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012]

fig = go.Figure()
fig.add_trace(go.Bar(x=years,
                     y=[219, 146, 112, 127, 124, 180, 236, 207, 236, 263,
                        350, 430, 474, 526, 488, 537, 500, 439],
                     name='Rest of world',
                     marker_color='rgb(55, 83, 109)',
                     width=0.1
                     ))

fig.update_layout(
    title='US Export of Plastic Scrap',
    xaxis_tickfont_size=14,
    yaxis=dict(
        title='USD (millions)',
        titlefont_size=16,
        tickfont_size=14,
    ),
    legend=dict(
        x=0,
        y=1.0,
        bgcolor='rgba(255, 255, 255, 0)',
        bordercolor='rgba(255, 255, 255, 0)'
    ),
    barmode='group',
    bargap=0,  # gap between bars of adjacent location coordinates.
)
fig.show()

The width reduction works but not the bargap.

Hi @adrian.s I’m not sure I understand what you want to do.

If you don’t specify explicitly the xaxis range, the whole domain of the xaxis (which is a bit smaller than the figure width by default) is taken by your data xaxis range. The width attribute of go.Bar is given in data coordinates (ie here it is a fraction of year). Conversely the bargap attribute of go.Layout is given as a fraction of the interval between consecutive x values.

So if you want to compress the figure, the most obvious thing to do is to reduce the width of the figure (a layout attribute), then you can change the domain or the range of the xaxis (fig.update_xaxes).

Hi @Emmanuelle, thanks a lot for answering.
It seems that what I want to do is not possible. I also read in the Plotly Reference that bargap does not work when width is specified. Which in a way makes sense.

But to be clearer on what I want to do, here is a much closer repro of the problem I have:

import plotly.graph_objects as go
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State

app = dash.Dash(__name__, meta_tags=[{"name": "viewport", "content": "width=device-width"}])

app.layout = html.Div(
    [
        dcc.RadioItems(
            id='filter',
            options=[
                {'label': "One", 'value': "One"},
                {'label': "Two", 'value': "Two"},
            ],
            value="One",
        ),
        html.Div(
            dcc.Graph(
                id="graph",
                config={
                "responsive": True,
                'displayModeBar': False,
                },
            ),
            style={
                "maxHeight": "35vh",
                "maxWidth": "40vw",
                "padding": "0",
                "overflowY": "scroll",
                "borderColor":"black",
                "border":"solid"
            }
        )
    ]
)

@app.callback(
    Output("graph","figure"),
    [
        Input("filter","value")
    ]
)
def graph(value):
    if value == "One":
        years = [1995, 1996, 1997,
                1998, 1999, 2000, 2001, 2002, 2003,
                2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
                ]

        fig = go.Figure()
        fig.add_trace(go.Bar(y=years,
                            x=[219, 146, 112,
                                127, 124, 180, 236, 207, 236, 263,
                                350, 430, 474, 526, 488, 537, 500, 439
                                ],
                            name='Rest of world',
                            marker_color='rgb(55, 83, 109)',
                            orientation="h"
                            ))

        fig.update_layout(
            margin={"t": 20, "l": 20, "r": 20, "b": 20},
            xaxis_tickfont_size=15,
            yaxis=dict(
                title='USD (millions)',
                titlefont_size=16,
                tickfont_size=14,
            ),
            legend=dict(
                #x=0,
                #y=1.0,
                bgcolor='rgba(255, 255, 255, 0)',
                bordercolor='rgba(255, 255, 255, 0)'
            ),
            barmode='group',
            bargap=0.1,
            autosize=True
        )
        return fig
    
    elif value == "Two":
        years = [1995, 1996, 1997]

        fig = go.Figure()
        fig.add_trace(go.Bar(y=years,
                            x=[219, 146, 112],
                            name='Rest of world',
                            marker_color='rgb(55, 83, 109)',
                            orientation="h"
                            ))

        fig.update_layout(
            margin={"t": 20, "l": 20, "r": 20, "b": 20},
            xaxis_tickfont_size=15,
            yaxis=dict(
                title='USD (millions)',
                titlefont_size=16,
                tickfont_size=14,
            ),
            legend=dict(
                #x=0,
                #y=1.0,
                bgcolor='rgba(255, 255, 255, 0)',
                bordercolor='rgba(255, 255, 255, 0)'
            ),
            barmode='group',
            bargap=0.1,
            autosize=True
        )
        return fig

if __name__ == "__main__":
    app.run_server(host="127.0.0.1", port=8050, debug=True)

I have a div that has a graph in it. The graph is changed by some filters. Sometimes I have many elements in it, sometimes only a few. When I have few elements that would fit the div, they should size accordingly and when there are many elements I can scroll. Having few items that are very big is not desirable.

What I wanted to do in my original question is to fix width and bargap, so that this doesn’t happen.

Have you found any solution?
I want to do the exact thing and the filters are messing with the width of the bar chart