Hi @mingw64 ,
You can make that plot, but off course need custom modification than just scatter plot.
The idea is to hide axis lines and grid lines , then create another line shape to “replace” hidden axis line.
If you want to add tick labels, redefine the tick labels between the min and max value of each axis using tickmode="array"
and generate tickvals
from min/max value with interval that you want.
Here the example.
import plotly.express as px
import numpy as np
df = px.data.iris()
fig = px.scatter(df, x="sepal_length", y="sepal_width")
x = df.sepal_length
y = df.sepal_width
# get min max, idxmin, and idxmax each axis
min_y, max_y = y.min(),y.max()
idxmin_y, idxmax_y = y.idxmin(),y.idxmax()
min_x, max_x = x.min(),x.max()
idxmin_x, idxmax_x = x.idxmin(),x.idxmax()
xaxis_pad = 0.2 # padding from min/max value to axis line
yaxis_pad = 0.2 # padding from min/max value to axis line
# define new range to easier put dashed line in min and max value
new_x_range = (min_x- xaxis_pad, max_x + xaxis_pad)
new_y_range = (min_y- yaxis_pad, max_y + yaxis_pad)
# draw min x line
fig.add_shape(type="line",
x0=min_x, y0=new_y_range[0], x1=min_x, y1=y.iloc[idxmin_x],
line=dict(
color="grey",
width=2,
dash="dot",
)
)
# draw max x line
fig.add_shape(type="line",
x0=max_x, y0=new_y_range[0], x1=max_x, y1=y.iloc[idxmax_x],
line=dict(
color="grey",
width=2,
dash="dot",
)
)
# draw min y line
fig.add_shape(type="line",
x0=new_x_range[0], y0=min_y, x1=x.iloc[idxmin_y], y1=min_y,
line=dict(
color="grey",
width=2,
dash="dot",
)
)
# draw max y line
fig.add_shape(type="line",
x0=new_x_range[0], y0=max_y, x1=x.iloc[idxmax_y], y1=max_y,
line=dict(
color="grey",
width=2,
dash="dot",
)
)
# draw custom x axis line
fig.add_shape(type="line",
x0=min_x, y0=new_y_range[0], x1=max_x, y1=new_y_range[0],
line=dict(
color="grey",
width=2,
)
)
# draw custom y axis line
fig.add_shape(type="line",
x0=new_x_range[0], y0=min_y, x1=new_x_range[0], y1=max_y,
line=dict(
color="grey",
width=2,
)
)
# set plot background color white
fig.update_layout(plot_bgcolor="white",)
fig.update_xaxes(showline=False, # hide xaxislie
showgrid=False, # hide grid line
range=new_x_range, # set xaxis range
tickmode="array", tickvals=list(np.arange(min_x, max_x,0.5)) # set x tick labels
)
fig.update_yaxes(showline=False, # hide y axis line
showgrid=False, # hide grid line
range=new_y_range, # set yaxis range
tickmode="array", tickvals=list(np.arange(min_y, max_y,0.5)) # set y tick labels
)
fig.show()