Hello Laotu,
With more recent versions of Plotly you can style your markers pretty much as you like.
I think the styling of markers wasn’t possible in Plotly about 9 months ago when I asked the above question.
I need the same marker style as you to create a tadpole plot and came up with the following solution:
import numpy as np
import plotly.graph_objs as go
import plotly.express as px
from ipywidgets import interactive, HBox, VBox, widgets, interact, fixed,
interact_manual, Layout, Button, Box, FloatText, Textarea, Dropdown,
Label, IntSlider
from IPython.display import display, HTML
display(HTML(“.container { width:100% !important; }”))
“”" FUNCTION TO UPDATE FIGURE-WIDGET. “”"
def update1(XAxis, xAxisTuple):
# The following two function arguments are not used on the subsequent lines.
print('type(XAxis.range) =', type(XAxis.range))
print('type(xAxisTuple) =', type(xAxisTuple))
with f1.batch_update():
xAxMin = f1.layout.xaxis['range'][0]
print(xAxMin)
xAxMax = f1.layout.xaxis['range'][1]
print(xAxMax)
yAxMin = f1.layout.yaxis['range'][0]
print(yAxMin)
yAxMax = f1.layout.yaxis['range'][1]
print(yAxMax)
# Corrective term accounting for ratio of axes ranges.
fac1 = (xAxMax-xAxMin) / (yAxMax-yAxMin)
# Corrective term accounting for window size and figure margins.
fac2 = (heig-bordT-bordB)/(wid-bordL-bordR)
fac3 = (1000-bordT-bordB)/(heig-bordT-bordB)
print(fac2)
# Adjustment term for chosen value for variable l = 0.0042
fac4 = (yAxMax-yAxMin)/3
f1.data[1].x = df['sepal_width']
f1.data[1].y = df['sepal_length']
f1.data[1].x = df['sepal_width'] + l * np.cos(np.deg2rad(-ang))*fac1*fac2*fac3*fac4
f1.data[1].y = df['sepal_length'] + l * np.sin(np.deg2rad(-ang))*fac3*fac4
“”" LOADING DATA AND SETTING SOME FIGURE PARAMETERS. “”"
df = px.data.iris()
ang = 120
XaxRange = [2, 5]
YaxRange = [4, 9]
wid = 1000
heig = 800
bordL = 10
bordR = 10
bordT = 10
bordB = 10
l = 0.042
“”" TRACE 1, CIRCLE MARKERS. “”"
fig1 = px.scatter(df, x=‘sepal_width’, y=‘sepal_length’)
fig1.update_traces(marker=dict(size=8,
symbol=“circle”,
line=dict(width=2, color=“DarkSlateGrey”)),
selector=dict(mode=“markers”),
showlegend=False,
marker_color=‘LightSteelBlue’)
“”" TRACE 2, LINE MARKERS “”"
DEFINITION OF POSITIONS OF LINE MARKERS.
Corrective term accounting for ratio of axes ranges.
fac1 = (XaxRange[1]-XaxRange[0]) / (YaxRange[1]-YaxRange[0])
Corrective term accounting for window size and figure margins.
fac2 = (heig-bordT-bordB)/(wid-bordL-bordR)
fac3 = (1000-bordT-bordB)/(heig-bordT-bordB)
Adjustment term for chosen value for variable l = 0.042
fac4 = (YaxRange[1]-YaxRange[0])/3
df[‘x’] = df[‘sepal_width’] + l * np.cos(np.deg2rad(-ang)) * fac1 * fac2 * fac3 * fac4
df[‘y’] = df[‘sepal_length’] + l * np.sin(np.deg2rad(-ang)) * fac3 * fac4
fig2 = px.scatter(df, x=‘x’, y=‘y’)
fig2.update_traces(marker=dict(size=12,
symbol=“line-ew”,
angle=ang,
line=dict(width=2, color=“DarkSlateGrey”)),
selector=dict(mode=“markers”),
showlegend=False)
“”" FIGURE-WIDGET COMBINING TRACES 1 AND 2. “”"
fig3 = go.Figure(data=fig1.data + fig2.data,
layout_xaxis_range=XaxRange,
layout_yaxis_range=YaxRange)
fig3.update_layout(margin=dict(l=bordL, r=bordR, t=bordT, b=bordB),
paper_bgcolor=“LightSteelBlue”,
width=wid, height=heig)
f1 = go.FigureWidget(fig3)
display(f1)
f1.layout.xaxis.on_change(update1, ‘range’)