How to add two sets of arrows with different colours, please? I obtained just green arrows. Are red arrows overplotted? How to suppress that?
When I comment the part between ###, I have red arrows.
The desired result is to have both arrows - red and green.
Thank you
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
d = {'a': [1, 2, 2], 'b': [3, 5, 4], 'c': [0.1, 0.2, 0.6]}
df = pd.DataFrame(data=d)
fig = px.scatter(df, x='a', y='b', error_y='c')
fig.update_xaxes(title_font_family="Trebuchet")
fig.update_layout(yaxis=dict(scaleanchor="x", scaleratio=1),
template = "plotly_white",
title="<b>V</b>",
)
fig.update_layout(xaxis = dict(autorange="reversed"))
x_end = [1, 2, 2]
y_end = [3, 5, 4]
x_start = [0, 1, 3]
y_start = [4, 4, 4]
list_of_all_arrows = []
for x0,y0,x1,y1 in zip(x_end, y_end, x_start, y_start):
arrow = go.layout.Annotation(dict(
x=x0,
y=y0,
xref="x", yref="y",
text="",
showarrow=True,
axref="x", ayref='y',
ax=x1,
ay=y1,
arrowhead=3,
arrowwidth=1.5,
arrowcolor='rgb(255,51,0)',)
)
list_of_all_arrows.append(arrow)
fig.update_layout(annotations=list_of_all_arrows)
###
list_of_all_arrows2 = []
for x0,y0,x1,y1 in zip([i-2 for i in x_end], [i-3 for i in y_end], x_start, y_start):
arrow = go.layout.Annotation(dict(
x=x0,
y=y0,
xref="x", yref="y",
text="",
showarrow=True,
axref="x", ayref='y',
ax=x1,
ay=y1,
arrowhead=3,
arrowwidth=1.5,
arrowcolor='green',)
)
list_of_all_arrows2.append(arrow)
fig.update_layout(annotations=list_of_all_arrows2)
###
# fig.write_html("Fig.html")
fig.show()
CodePudding user response:
The origin of the problem is that in the background figures in plotly are dictionaries. The fact that you are calling two times fig.update_layout(annotations=list_anotation)
updates figure's dictionary annotations entry. To check the dictionary of a figure just print the figure print(fig)
, there you can see the key layout
and sub key annotations
.
Therefore only calling one the function update_layout works as you want.
Step1: delete this line
fig.update_layout(annotations=list_of_all_arrows) # delete this line
Step2: change last line
fig.update_layout(annotations=list_of_all_arrows2 list_of_all_arrows)
this is equivalent to appending all arrows to a single list
Total code
import plotly.express as px
import numpy as np
import pandas as pd
import plotly.graph_objects as go
d = {'a': [1, 2, 2], 'b': [3, 5, 4], 'c': [0.1, 0.2, 0.6]}
df = pd.DataFrame(data=d)
fig = px.scatter(df, x='a', y='b', error_y='c')
fig.update_xaxes(title_font_family="Trebuchet")
fig.update_layout(yaxis=dict(scaleanchor="x", scaleratio=1),
template = "plotly_white",
title="<b>V</b>",
)
fig.update_layout(xaxis = dict(autorange="reversed"))
x_end = [1, 2, 2]
y_end = [3, 5, 4]
x_start = [0, 1, 3]
y_start = [4, 4, 4]
list_of_all_arrows = []
for x0,y0,x1,y1 in zip(x_end, y_end, x_start, y_start):
arrow = go.layout.Annotation(dict(
x=x0,
y=y0,
xref="x", yref="y",
text="",
showarrow=True,
axref="x", ayref='y',
ax=x1,
ay=y1,
arrowhead=3,
arrowwidth=1.5,
arrowcolor='rgb(255,51,0)',)
)
list_of_all_arrows.append(arrow)
list_of_all_arrows2 = []
for x0,y0,x1,y1 in zip([i-2 for i in x_end], [i-3 for i in y_end], x_start, y_start):
arrow = go.layout.Annotation(dict(
x=x0,
y=y0,
xref="x", yref="y",
text="",
showarrow=True,
axref="x", ayref='y',
ax=x1,
ay=y1,
arrowhead=3,
arrowwidth=1.5,
arrowcolor='green',)
)
list_of_all_arrows2.append(arrow)
fig.update_layout(annotations=list_of_all_arrows2 list_of_all_arrows)