I have a dataframe as such:
Starting point Walking Driving
Lunch 0 8 4
Shopping 0 7 3
Coffee 0 5 2
Where I want to draw, for each index, a green line from "Starting point" -> "Walking", and a red line from "Starting point" -> "Coffee". To do this, I loop through both the columns and the index, as such:
for column in df7.columns:
for idx in df7.index:
fig9.add_trace(
go.Scatter(
# chart
# chart
# chart
)
)
Which gives me the following chart of two lines, colored by cycle, overlapping.
The question is: how can I modify the code in plotly python to create jitter in the y axis for the lines of different cycles? In other words, the shorter line will be above the longer line.
Full MRE:
df7 = pd.DataFrame({
'Starting point': [0, 0, 0],
'Walking': [8, 7, 5],
'Biking': [4, 3, 2]
}, index=['Lunch', 'Shopping', 'Coffee'])
fig9 = go.Figure()
color_cyc = cycle(["#888888", "#E2062B"])
symbol_cyc = cycle(["diamond", "cross"])
for column in df7.columns:
color=next(color_cyc)
for idx in df7.index:
fig9.add_trace(
go.Scatter(
y=[idx] * len(df7.loc[idx, ["Starting point", column]]),
x=df7.loc[idx, ["Starting point", column]],
showlegend=False,
mode="lines+markers",
marker={
"color": color,
"symbol": "diamond",
# "jitter": 0.4,
},
),
)
fig9
Thanks very much.
Answer
Try to use offset and then enumerate
import pandas as pd
import plotly.graph_objects as go
from itertools import cycle
df7 = pd.DataFrame({
'Starting point': [0, 0, 0],
'Walking': [8, 7, 5],
'Biking': [4, 3, 2]
}, index=['Lunch', 'Shopping', 'Coffee'])
fig9 = go.Figure()
color_cyc = cycle(["#888888", "#E2062B"])
symbol_cyc = cycle(["diamond", "cross"])
col_offsets = {'Walking': 0.15, 'Biking': -0.15}
for column in ['Walking', 'Biking']:
color = next(color_cyc)
offset = col_offsets[column]
for i, idx in enumerate(df7.index):
y_val = i + offset
fig9.add_trace(
go.Scatter(
y=[y_val, y_val],
x=[df7.loc[idx, "Starting point"], df7.loc[idx, column]],
showlegend=False,
mode="lines+markers",
marker=dict(
color=color,
symbol="diamond"
),
line=dict(color=color)
)
)
fig9.update_yaxes(
tickvals=list(range(len(df7.index))),
ticktext=list(df7.index)
)
fig9.show()