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