顶部子图工作正常但底部的箭头开始/结束样式与顶部子图不同!
import re
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
def plot_line(df,pngname):
fontsize = 10
title = "demo"
xlabel = "KeyPoint"
ylabel = "Duration(secs)"
xname = df.columns[0]
colnames = df.columns[1:]
n = len(colnames)
fig = make_subplots(
rows=n, cols=1,
shared_xaxes=True,
vertical_spacing = 0.02,
)
xaxis,yaxis = get_xyaxis()
for i,yname in enumerate(colnames):
trace1 = go.Scatter(
x=df[xname],
y=df[yname],
text=df[yname],
textposition='top center',
mode='lines+text',
marker=dict(
size=1,
line=dict(width=0,color='DarkSlateGrey')),
name=yname)
fig.add_trace(
trace1,
row=i+1,
col=1
)
fig.update_xaxes(xaxis)
fig.update_yaxes(yaxis)
add_anns(fig,df,xname,yname,i+1,1)
xpading=.05
fig.update_layout(
margin=dict(l=20,t=40,r=10,b=40),
plot_bgcolor='#ffffff',#'rgb(12,163,135)',
paper_bgcolor='#ffffff',
title=title,
title_x=0.5,
showlegend=True,
legend=dict(x=.02,y=1.05),
barmode='group',
bargap=0.05,
bargroupgap=0.0,
font=dict(
family="Courier New, monospace",
size=fontsize,
color="black"
),
)
fig.show()
return
def get_xyaxis():
xaxis=dict(
title_standoff=1,
tickangle=-15,
showline=True,
linecolor='black',
color='black',
linewidth=.5,
ticks='outside',
showgrid=True,
gridcolor='grey',
gridwidth=.5,
griddash='solid',#'dot',
)
yaxis=dict(
title_standoff=1,
showline=True,
linecolor='black',
color='black',
linewidth=.5,
showgrid=True,
gridcolor='grey',
gridwidth=.5,
griddash='solid',#'dot',
zeroline=True,
zerolinecolor='grey',
zerolinewidth=.5,
showticklabels=True,
)
return [xaxis,yaxis]
def add_anns(fig,df,xname,yname,i,j):
prev = df.loc[0]
for idx, row in df.iterrows():
dy = row[yname] - prev[yname]
x0 = row[xname]
y0 = row[yname]
x1 = row[xname]
y1 = prev[yname]
if abs(dy) > 0:
ans = add_vline(fig,x0,y0,y1,i,j,"%.1f"%(dy))
prev = row
return
def add_vline(fig,x0,y0,y1,row,col,text=None):
dw = 10 # pixels
if text == None:
text = "%.1f"%(y1-y0)
anns = []
xref='x'
yref='y'
fig.add_annotation(#vertical1
x=x0,y=y0,ax=x0,ay=y1,
xref=xref,yref=yref,axref=xref,ayref=yref,
showarrow=True,text='',
arrowhead=2,arrowside='start+end',arrowsize=2,arrowwidth=.5,arrowcolor='black',
row=row,col=col,
)
fig.add_annotation(# start
x=x0,y=y0,ax=-dw,ay=y0,
xref=xref,yref=yref,axref='pixel',ayref=yref,
showarrow=True,text='',arrowwidth=.5,arrowcolor='black',
row=row,col=col,
)
fig.add_annotation(
x=x0,y=y0,ax=dw,ay=y0,
xref=xref,yref=yref,axref='pixel',ayref=yref,
showarrow=True,text='',arrowwidth=.5,arrowcolor='black',
row=row,col=col,
)
fig.add_annotation( # end
x=x0,y=y1,ax=-dw,ay=y1,
xref=xref,yref=yref,axref='pixel',ayref=yref,
showarrow=True,text='',arrowwidth=.5,arrowcolor='black',
row=row,col=col,
)
fig.add_annotation(
x=x0,y=y1,ax=dw,ay=y1,
xref=xref,yref=yref,axref='pixel',ayref=yref,
showarrow=True,text='',arrowwidth=.5,arrowcolor='black',
row=row,col=col,
)
fig.add_annotation(# text label
x=x0, y=(y0+y1)/2,
xref=xref,yref=yref,
text=text,textangle=0,font=dict(color='black',size=14),
bgcolor='white',
showarrow=False,arrowhead=1,arrowwidth=2,
row=row,col=col,
)
return
def main():
data = [
['AAA',1,2],
['BBB',10,12],
['CCC',5,6],
['DDD',8,9],
]
df = pd.DataFrame(data,columns=['name','v1','v2'])
plot_line(df,"./demo.png")
return
main()
我不确定为什么会这样。似乎要获得两个预期的箭头,我需要指定要引用的每个轴。
def add_vline(fig,x0,y0,y1,row,col,text=None):
print(row,col)
dw = 10 # pixels
if text == None:
text = "%.1f"%(y1-y0)
print(text)
anns = []
xref='x' if row == 1 else 'x2' # update
yref='y' if row == 1 else 'y2' # update
fig.add_annotation(
...
)