Hi,
I am using “fig.show(config={‘modeBarButtonsToAdd’:[‘drawline’]})” to be able to manually draw lines in my Plotly charts.
How do I configure the line width to be thinner for the lines I draw?
Thanks
HI @robin1, not sure if you are referring to the line width of a line chart:
import plotly.express as px
x=[1,2]
y=[1,2]
fig = px.line(x=x, y=y)
fig.update_traces(line={'width': 10})
creates:
Thanks for your reply.
If I add “fig.update_traces(line={‘width’: 10})” it only adjusts the width of the lines drawn by my program in the chart. It does not change the width of the lines I draw manually with the mouse when clicking on the drawline-button at the top right in the chart. Any idea how to adjust that line width? I am using a go.Candlestick chart.
hi @robin1
As far as I know, there is no out-of-the-box way to manage the width of the line that you draw with your mouse.
There are different types of annotations that you can make, but nothing about controlling the width.
to add to @adamschroeder’s comment: If you are open to using dash, there might be a possibility.
Thanks, I am familiar with using Dash. Any idea how I can do that in Dash?
Hi, @robin1,
do you want to change the thickness of an existing line or define the thickness of the lines the user might draw?
The latter can be configured like this:
newshape={'line': {'color': 'crimson', 'width': 7}}
Full example:
import pandas as pd
import plotly.express as px
import numpy as np
MONTHS = 14
vals = np.random.randint(2, 20, size=MONTHS)
months = pd.Series(pd.date_range("1/1/2023", freq="M", periods=MONTHS))
fig = px.bar(x=months, y=vals)
fig.update_layout({
'xaxis': {
'tickformat': '%y/%m',
'tickvals': months
}
})
fig.update_layout(dragmode='drawline',
# style of new shapes
newshape={'line': {'color': 'crimson', 'width': 7}})
fig.show(config={'modeBarButtonsToAdd':['drawline',
'drawopenpath',
'drawclosedpath',
'drawcircle',
'drawrect',
'eraseshape'
]})
mrep shape color
Here an example changing (in this case ONE) existing line in Dash:
import dash
from dash import Input, Output, html, dcc, State
import plotly.graph_objects as go
import numpy as np
# create figure
figure = go.Figure(
data=go.Heatmap(z=np.ones(shape=(20, 20))),
layout={
'newshape': {
'line': {
# signal yellow
'color': '#E2F714',
'width': 6,
}
}
}
)
# add some buttons
config = {
'modeBarButtonsToAdd': [
'drawline',
'eraseshape'
]
}
app = dash.Dash(__name__)
app.layout = html.Div([
html.Button('update line', id='btn'),
dcc.Dropdown(
id='color',
options=['gold', 'red', 'green'],
value='red'),
dcc.Dropdown(
id='dash',
options=['solid', 'dash', 'dot'],
value='dot'),
dcc.Dropdown(
id='width',
options=[*range(10)],
value=5),
dcc.Graph(
id='graph',
figure=figure,
config=config),
])
@app.callback(
Output('graph', 'figure'),
Input('btn', 'n_clicks'),
State('graph', 'figure'),
State('color', 'value'),
State('dash', 'value'),
State('width', 'value'),
prevent_initial_call=True
)
def update(_, fig, color, line_style, width):
new_line_style = {
"line": {
"color": color,
"width": width,
"dash": line_style
}
}
# update line
fig['layout']['shapes'][0].update(new_line_style) # [0] --> assuming there is only one line drawn
return fig
if __name__ == '__main__':
app.run(debug=True, port=8051)
Thank you very much!
All I had to do was to add the line “fig.update_layout(newshape={‘line’: {‘width’: 1}})” to get thin beautiful precision lines that can be drawn by the user.