Plotly:如何找到并注释两条线之间的交点? [英] Plotly: How to find and annotate the intersection point between two lines?

查看:127
本文介绍了Plotly:如何找到并注释两条线之间的交点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Plotly 查找和注释两条线的交点.我知道我们可以使用 (plt.plot(*intersection.xy,'ko')) 来获取 Mathplotlib 中的交点,但是如何在 plotly 中做到这一点,或者是否可以做到.

将 numpy 导入为 np将熊猫导入为 pd导入 plotly.express 作为 pxtest = pd.merge(ps,uts,on = '时间')打印(测试)时间=测试['时间']omfr = test['孔板质量流量']qab = 测试['Qab']fig = px.line(test, x=time, y=[omfr,qab])fig.update_layout(title='管道应力和 UTS (MPa)',xaxis_title=时间 (s)",yaxis_title=管道应力和 UTS (MPa)",悬停模式='x')

代码输出:

交点:

解决方案

注释和显示交集很容易.找到是困难的部分,我在这方面的建议直接建立在

编辑 - 注释

如果您想更改文本注释,只需更改

text="intersect";

... 类似于:

text = '线在 x = ' + str(round(x[0], 2)) + ' 和 y = ' + str(round(y[0], 2)) 处相交

结果:

完整代码

将pandas导入为pd导入 plotly.graph_objects as go将 numpy 导入为 np# 导入破折号# 示例数据框df = pd.DataFrame()df['x'] = np.arange(4) +1df['y1'] = df['x']**3df['y2'] = [10+val**2.2 for df['x']] 中的 val# 交叉点def_rect_inter_inner(x1,x2):n1=x1.shape[0]-1n2=x2.shape[0]-1X1=np.c_[x1[:-1],x1[1:]]X2=np.c_[x2[:-1],x2[1:]]S1=np.tile(X1.min(axis=1),(n2,1)).TS2=np.tile(X2.max(axis=1),(n1,1))S3=np.tile(X1.max(axis=1),(n2,1)).TS4=np.tile(X2.min(axis=1),(n1,1))返回 S1,S2,S3,S4def _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)返回 ii,jj定义交叉点(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,:]=-1AA[2:4,3,:]=-1AA[0::2,0,:]=dxy1[ii,:].TAA[1::2,1,:]=dxy2[jj,:].TBB=np.zeros((4,n))BB[0,:]=-x1[ii].ravel()BB[1,:]=-x2[jj].ravel()BB[2,:]=-y1[ii].ravel()BB[3,:]=-y2[jj].ravel()对于范围(n)中的我:尝试:T[:,i]=np.linalg.solve(AA[:,:,i],BB[:,i])除了:T[:,i]=np.NaNin_range= (T[0,:] >=0) &(T[1,:] >=0) &(T[0,:] <=1) &(T[1,:] <=1)xy0=T[2:,in_range]xy0=xy0.T返回 xy0[:,0],xy0[:,1]# 情节图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,模式 = '标记',标记=dict(line=dict(color='black', width = 2),符号 = '钻石',大小 = 14,颜色 = 'rgba(255, 255, 0, 0.6)'),名称 = '相交'),)fig.add_annotation(x=x[0], y=y[0],# text="相交",text = '线在 x = ' + str(round(x[0], 2)) + ' 和 y = ' + str(round(y[0], 2)) 处相交,font=dict(family=sans serif",大小=18,颜色=黑色"),轴=0,y=-100,显示箭头=真,箭头=1)图.show()

I am trying to find and annotate the intersection point of two-line using Plotly. I know we can use (plt.plot(*intersection.xy,'ko')) to get the intersection point in Mathplotlib, but how can do it in plotly or if it can be done.

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:

解决方案

Annotating and showing the intersection is easy. Finding it is the hard part, and my suggestion in that regard builds directly on the contributions in the post How do I compute the intersection point of two lines. I'll include a few lines on the details in my suggestion when I find the time. For now, the complete code snippet at the end of my answer will produce the following figure using this dataset:

Data

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

Plot

Edit - Annotation

If you'd like to change the text annotation, just change

text="intersect"

... to something like:

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

Result:

Complete code

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()

这篇关于Plotly:如何找到并注释两条线之间的交点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆