Plotly:当 2 行相互靠近时如何创建指针

Posted

技术标签:

【中文标题】Plotly:当 2 行相互靠近时如何创建指针【英文标题】:Plotly: How to create a pointer when 2 lines close over each other 【发布时间】:2021-07-29 09:04:27 【问题描述】:

如何在两条线的交点处创建一个指针?

【问题讨论】:

你能附上你用来生成这张图片的代码,以及DataFrame或DataFrame的样本吗? 【参考方案1】:

您的问题和Plotly: How to find and annotate the intersection point between two lines? 之间的唯一区别似乎是您的案例有多个交叉点。您仍然可以使用相同的approach described here,然后考虑多个交叉点的多个注释:

for x, y in zip(x,y):
    fig.add_annotation(x=x, y=y,
                       text = 'lines intersect at x = ' + str(round(x, 2)) + ' and y = ' + str(round(y, 2)),
                       font=dict(family="sans serif", size=18, color="black"),
                        ax=0,
                        ay=-100,
                        showarrow=True,
                        arrowhead=1)

完整代码:

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']]

df2 = pd.DataFrame('x':[5,6,7],
                    'y1':[60, 50, 10],
                    'y2':[26,20,19])

df = pd.concat([df, df2])

# 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'),
              )

for x, y in zip(x,y):
    fig.add_annotation(x=x, y=y,
                       text = 'lines intersect at x = ' + str(round(x, 2)) + ' and y = ' + str(round(y, 2)),
                       font=dict(family="sans serif", size=18, color="black"),
                        ax=0,
                        ay=-100,
                        showarrow=True,
                        arrowhead=1)

fig.show()

【讨论】:

以上是关于Plotly:当 2 行相互靠近时如何创建指针的主要内容,如果未能解决你的问题,请参考以下文章

C语言零碎知识点之定义指针时星号靠近类型名还是变量名

void指针意义Constvolatile#definetypedef接续符

关于二级指针与一级指针相互转换的问题!

如何检测两只乌龟是不是彼此靠近或相互接触

使用 char** argv 时如何避免指针运算

如何从 Swift 3 中的不透明指针创建类型化指针?