Black Lives Matter. Please consider donating to Black Girls Code today.

Draw lines and save them

Hey,

I’m currently using the on line chart editor in order to load some subplots, draw lines on then and save back to my db.

Is it possible to do the same with dash?

  1. Create a button for creating a line
  2. Having the defaults of each line be the “selected” axes I clicked on?

It should be! You’ll need to set config=dict(editable=True) inside the dcc.Graph in order to be able to interactively move the lines around.

The callbacks would be:
Output('graph', 'figure'), [Input('add-line', 'n_clicks')]

and
Output('save-status', 'children'), [Input('save-lines', 'n_clicks')], [State('graph', 'figure')]

2 Likes

wait, wait, wait!

You just might made my dream come true.

my final goal is to create something like this

the main functionalities are:

  1. each graph is
    1.1 zoom-able by scroll
    1.2 pan-able
    1.3 y axis is stretch-able.
  2. Once I click on a graph, it is “clicked”, and then I can draw a line on it’s axis.
  3. each line appears to the left of the graph where I can give it a name.
  4. the SAVE button saves my line to my db.
  5. the next/back buttons are for loading the next X graphs.

please tell me that is doable with dash syntax and not a big headache?

thank you,

Yeah, I think it would be. Please share your code once you get going!

This is my current code using plotly regular api (?) and then working the lines in chart editor.

I have no idea how to use dash.

Can you give me some guidelines as to what functions to begin with?
events? buttons? zoom/pan/stretch graph?

import pandas as pd
import numpy as np
example_data = {}
for i in range(2):
    df = pd.DataFrame(index=pd.date_range(start = "06/01/2018", end = "08/01/2018"), data = np.random.rand(62)*100)
    example_data[i] = df


traces = collections.OrderedDict()
num_to_name = {}
name_to_yref = {}
num_counter = 1
yref_counter = 2
yref = 'y'
for df in stocks_dict:
    df_data=stocks_dict[df][stocks_dict[df].index.year>2016]
    num_to_name[num_counter] = df
    name_to_yref[df] = yref
    traces[df] = go.Candlestick(x=df_data.index,
                        open=df_data.adj_open, high=df_data.adj_high,low=df_data.adj_low,
                        close=df_data["adjusted close"], name = df)
    num_counter+=1
    yref = 'y' + str(yref_counter)
    yref_counter+=1
name_to_num = {v: k for k, v in num_to_name.items()}
yref_to_name = {v: k for k, v in name_to_yref.items()}



num_cols = 2
num_stocks = float(len(traces))
num_rows = int(np.ceil(num_stocks/num_cols))
fig = tools.make_subplots(rows=num_rows, cols=num_cols, subplot_titles=([df for df in stocks_dict]), horizontal_spacing=0.2,vertical_spacing=0.2)


curr_row = 1
curr_col = 1
for trace in traces:
    curr_trace = traces[trace]
    # print curr_row, curr_col
    fig.append_trace(curr_trace, curr_row, curr_col)
    curr_col+=1
    if curr_col % num_cols == 1:
        curr_col=1
        curr_row+=1


fig['layout'].update(height=700*num_rows, width=700*num_cols, title='Portfolio Stocks', 
                     showlegend=False)
fig['layout']['xaxis1'].update(dict(rangeslider = dict(visible= False)))
fig['layout']['xaxis2'].update(dict(rangeslider = dict(visible= False)))
fig['layout']['xaxis3'].update(dict(rangeslider = dict(visible= False)))
fig['layout']['xaxis4'].update(dict(rangeslider = dict(visible= False)))

py.iplot(fig, filename='Portfolio Stocks', config={'scrollZoom': True})
# plotly.offline.plot(fig, filename='Portfolio Stocks', config={'scrollZoom': True})

Yup, the best guidelines I can give you is the Dash User Guide that I wrote. I recommend working through the first few chapters: https://dash.plot.ly/. Once you’ve worked through that, my callback suggestions above (Draw lines and save them) will make a lot more sense.

Here is the highlights for creating a horizontal line. This can be used in the graph updated. The blue line running across is from the code below.

df['stochs_lower'] = 30
df['stochs_upper'] = 80
stochs_lower = df['stochs_lower']
stochs_upper = df['stochs_upper']
 lower_line = Scatter(
        x=NewDateTimes,
        y=stochs_lower,
        line=dict(dash='dash'),
        marker=dict(color='#00f'),
        legendgroup='MACD [Hist]',
        name='Lower Line',
        yaxis='y2'
    )
    data.append(lower_line)