Plotly:如何查找和注释两条直线之间的交点?

2024-09-27 23:15:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用Plotly找到并注释两条直线的交点。我知道我们可以使用(plt.plot(*intersection.xy,'ko'))在Mathplotlib中获得交点,但是如何在plotly中获得交点,或者是否可以获得交点

import numpy as np
import pandas as pd
import plotly.express as px

test = pd.merge(ps,uts,on = 'Time')
print(test)

time = test['Time']
omfr = test['Orifice Mass Flow Rate']
qab = test['Qab']

fig = px.line(test, x=time, y=[omfr,qab])
fig.update_layout( title='Pipe stress and UTS (MPa)',xaxis_title="Time (s)",yaxis_title="Pipe stress and UTS (MPa)",
                  hovermode='x')

代码的输出: Output of the code

交点: Intersection point


Tags: testimporttimetitleasfigplotlypd
1条回答
网友
1楼 · 发布于 2024-09-27 23:15:33

注释和显示交点很容易发现这是困难的部分,我在这方面的建议直接基于postHow do I compute the intersection point of two lines中的贡献。当我有时间的时候,我会在我的建议中加入几行关于细节的内容。现在,我的答案末尾的完整代码片段将使用此数据集生成下图:

数据

   x  y1  y2
0  1   1  11.00
1  2   8  14.59
2  3  27  21.21
3  4  64  31.11

绘图

enter image description here

编辑-注释

如果要更改文本批注,只需更改

text="intersect"

。。。例如:

text = 'lines intersect at x = ' + str(round(x[0], 2)) + ' and y = ' + str(round(y[0], 2))

结果:

enter image description here

完整代码

import pandas as pd
import plotly.graph_objects as go
import numpy as np
# import dash


# sample dataframe
df = pd.DataFrame()
df['x'] = np.arange(4) +1
df['y1'] = df['x']**3
df['y2'] = [10+val**2.2 for val in df['x']]

# intersection stuff
def _rect_inter_inner(x1,x2):
    n1=x1.shape[0]-1
    n2=x2.shape[0]-1
    X1=np.c_[x1[:-1],x1[1:]]
    X2=np.c_[x2[:-1],x2[1:]]
    S1=np.tile(X1.min(axis=1),(n2,1)).T
    S2=np.tile(X2.max(axis=1),(n1,1))
    S3=np.tile(X1.max(axis=1),(n2,1)).T
    S4=np.tile(X2.min(axis=1),(n1,1))
    return S1,S2,S3,S4

def _rectangle_intersection_(x1,y1,x2,y2):
    S1,S2,S3,S4=_rect_inter_inner(x1,x2)
    S5,S6,S7,S8=_rect_inter_inner(y1,y2)

    C1=np.less_equal(S1,S2)
    C2=np.greater_equal(S3,S4)
    C3=np.less_equal(S5,S6)
    C4=np.greater_equal(S7,S8)

    ii,jj=np.nonzero(C1 & C2 & C3 & C4)
    return ii,jj

def intersection(x1,y1,x2,y2):

    ii,jj=_rectangle_intersection_(x1,y1,x2,y2)
    n=len(ii)

    dxy1=np.diff(np.c_[x1,y1],axis=0)
    dxy2=np.diff(np.c_[x2,y2],axis=0)

    T=np.zeros((4,n))
    AA=np.zeros((4,4,n))
    AA[0:2,2,:]=-1
    AA[2:4,3,:]=-1
    AA[0::2,0,:]=dxy1[ii,:].T
    AA[1::2,1,:]=dxy2[jj,:].T

    BB=np.zeros((4,n))
    BB[0,:]=-x1[ii].ravel()
    BB[1,:]=-x2[jj].ravel()
    BB[2,:]=-y1[ii].ravel()
    BB[3,:]=-y2[jj].ravel()

    for i in range(n):
        try:
            T[:,i]=np.linalg.solve(AA[:,:,i],BB[:,i])
        except:
            T[:,i]=np.NaN


    in_range= (T[0,:] >=0) & (T[1,:] >=0) & (T[0,:] <=1) & (T[1,:] <=1)

    xy0=T[2:,in_range]
    xy0=xy0.T
    return xy0[:,0],xy0[:,1]

# plotly figure
x,y=intersection(np.array(df['x'].values.astype('float')),np.array(df['y1'].values.astype('float')),
                 np.array(df['x'].values.astype('float')),np.array(df['y2'].values.astype('float')))

fig = go.Figure(data=go.Scatter(x=df['x'], y=df['y1'], mode = 'lines'))
fig.add_traces(go.Scatter(x=df['x'], y=df['y2'], mode = 'lines'))
fig.add_traces(go.Scatter(x=x, y=y,
                          mode = 'markers',
                          marker=dict(line=dict(color='black', width = 2),
                                      symbol = 'diamond',
                                      size = 14,
                                      color = 'rgba(255, 255, 0, 0.6)'),
                         name = 'intersect'),
              )
fig.add_annotation(x=x[0], y=y[0],
                    # text="intersect",
                    text = 'lines intersect at x = ' + str(round(x[0], 2)) + ' and y = ' + str(round(y[0], 2)),
                    font=dict(family="sans serif",
                                  size=18,
                                  color="black"),
                    ax=0,
                    ay=-100,
                    showarrow=True,
                    arrowhead=1)

fig.show()

相关问题 更多 >

    热门问题