Home > Enterprise >  Two sets of arrows in plotly
Two sets of arrows in plotly

Time:09-13

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)

The final plot enter image description here

  • Related