Offset Plotly trace on x-axes

Viewed 1252

I'm trying to plot multiple categories on the same plot using add_trace(). Ideally, I would want the different traces to have a slight offset so that the markers don't overlap. I'm unable to figure how to achieve it.

Here is an illustrative code, and my current result. The add_trace() doesn't seem to have an argument for an offset.

import plotly.graph_objects as go
fig2 = go.Figure()

x_data = ['10 days', '20 days', '30 days']

y_data1 = [0.4, 0.7, 0.9]
y_err_data1 = [0.025, 0.03, 0.05]
y_data2 = [0.6, 0.65, 0.7]
y_err_data2 = [0.05, 0.03, 0.01]

fig2.add_trace(go.Scatter(x=x_data,
                             y=y_data1,
                             error_y = dict(type='data', symmetric=True,  array=y_err_data1, visible=True),
                             mode = 'markers'))

fig2.add_trace(go.Scatter(x=x_data,
                             y=y_data2,
                             error_y = dict(type='data', symmetric=True,  array=y_err_data2, visible=True),
                             mode = 'markers'))

fig2.show()

enter image description here

2 Answers

You can accomplish this with a couple modifications:

  • Use x_data=[10,20,30] so that we can easily add/subtract to it. Then for the x input of go.Scatter use something like x_data=[i-.1 for i in x_data] to create the offset. Select the offset you desire, I'm using +/- 0.1 here.
  • Alternatively you can use use a numpy array x_data=np.array([10,20,30]). Then the x input of go.Scatter is a easier with x=x_data-.1
  • Use ticksuffix=" days" to get the text back on your xaxis
  • Use tickvals=x_data to specify the exact tick values.

All together:

import plotly.graph_objects as go
import numpy as np
fig2 = go.Figure()

#x_data = [10,20,30]
x_data = np.array([10,20,30])

y_data1 = [0.4, 0.7, 0.9]
y_err_data1 = [0.025, 0.03, 0.05]
y_data2 = [0.6, 0.65, 0.7]
y_err_data2 = [0.05, 0.03, 0.01]

fig2.add_trace(go.Scatter(x=x_data+0.1, #x=[i+.1 for i in x_data]
                             y=y_data1,
                             error_y = dict(type='data', symmetric=True,  array=y_err_data1, visible=True),
                             mode = 'markers'))

fig2.add_trace(go.Scatter(x=x_data-0.1, #x=[i-.1 for i in x_data]
                             y=y_data2,
                             error_y = dict(type='data', symmetric=True,  array=y_err_data2, visible=True),
                             mode = 'markers'))

fig2.update_xaxes(ticksuffix=" days", tickvals=x_data)
fig2.show()

with tick vals

Another solution to get an offset between plotly box plots belonging to the same group is using the offsetgroup parameter together with the boxmode parameter, as below. You have to mess a little with the legend, otherwise it will show everything multiple times.

import plotly.graph_objects as go

colors={'SF Zoo': 'red', 'LA Zoo': 'blue'}

fig = go.Figure(
    data=[
        go.Box(x0='giraffes', name='SF Zoo', y=[1, 2, 3], offsetgroup="SF Zoo", line_color=colors['SF Zoo']),
        go.Box(x0='giraffes', name='LA Zoo', y=[3, 4, 5], offsetgroup="LA Zoo", line_color=colors['LA Zoo']),
        go.Box(x0='elephants', name='SF Zoo', y=[1, 2, 3], offsetgroup="SF Zoo", line_color=colors['SF Zoo'], showlegend=False),
        go.Box(x0='elephants', name='LA Zoo', y=[0, 1, 2, 4], offsetgroup="LA Zoo", line_color=colors['LA Zoo'], showlegend=False)
    ]
)

fig.update_layout(boxmode='group')
fig.show()

enter image description here

Related