Black Lives Matter. Please consider donating to Black Girls Code today.
Learn how to use COVID-19 data in open source Dash apps. Register for the Sept 23rd webinar with IQT!

Multiple overlaid axis title placement


I’m using Plotly to plot multiple traces using several overlaid axes depending on the units of the underlying data. I’ve been following the example here: Multiple Axes
The trouble I’m having is that the adjusted domains and offsets of the labels are given as positions in graph relative coordinates. This means that depending on the size of the plot, I may end up with large gaps, or overlaps. It also means that the spacing of the labels doesn’t respect the size of the label itself.
Is there a way to get the axes to stack next to each other automatically?


Can you share an example of what you’ve tried so far to help us help you?

So I’m taking in a configuration of which axes need to be included in the plot, along with titles and other options. (Sorry for the CoffeeScript)

xCount = Object.keys(axes.x).length
domains =
    x: [0, 1]
    y: [.15 * (xCount), 1]
for ori in ['x', 'y']
    i = 1
    rights = 0
    lefts = 0
    bottoms = 1
    for id, axisData of axes[ori]
        # Generate the default axis display string
        defaultTitle = axisData.defaultName

        # If the axis has a norm, include that unit after a / (eg, V/g)
        if axisData.units.display.symbol and axisData.units.display.norm?.symbol
            defaultTitle += " (#{axisData.units.display.symbol}/#{axisData.units.display.norm.symbol})"
        # If there is no norm, just include the unit symbol if it exists
        else if axisData.units.display.symbol
            defaultTitle += " (#{axisData.units.display.symbol})"

        plotlyAxisKey = if i > 1 then ori + 'axis' + i else ori + 'axis'
        update[plotlyAxisKey] = {title: axisData.label or defaultTitle}
        update[plotlyAxisKey].anchor = 'free' #if ori == 'x' then 'y' else 'x'

        if ori == 'y'
            if axisData.opposite
                update[plotlyAxisKey].side = 'right'
                update[plotlyAxisKey].position = 1 - (0.05 * (rights))
                domains.x[1] -= .05
                update[plotlyAxisKey].side = 'left'
                update[plotlyAxisKey].position = 0.05 * (lefts)
                domains.x[0] += .05
            update[plotlyAxisKey].position = 0.15 * (bottoms)

So currently I’m shifting the y axis labels by .05 each, and the x axis labels by .15 each, which works out ok for my usual plot size.

But if I change to a smaller size, the labels start to overlap.

The easiest solution would be to increase the margins (in layout.margin.l and layout.margin.r) to ensure that there’s enough room for the axis titles to fit in. But, I can’t think of a magic solution for this here.

That said, we’ve been experimenting with graph view breakpoints in the workspace, where users can defined layout patches that get applied or not depend on the graph’s width/height. For example, a graph could have a set of axis position for div width between 500-1000 px and another for div <500 px. Here’s an example of breakpoint-like behavior in raw plotly.js, see