Exemple #1
0
def one_filter(plot, filter_col, filter_vals, filters_state, max_items):
    # Remove (FX) from column name; probaby temporary
    title = re.sub(r'\s*[(]F[0-9]+[)]\s*', '', filter_col)

    # Deduplicate and turn into name-value pairs, as required by MultiSelect.
    options = [(opt,) * 2 for opt in sorted(filter_vals)]

    multi_select = MultiChoice(
        title=title,
        width=int(plot.plot_width / 1.5),
        height=int(plot.plot_height / 8),
        max_items=max_items,
        options=options
    )

    multi_select.js_on_change('value', CustomJS(
        args=dict(filter_col=filter_col,
                  filters_state=filters_state),
        code="""
        let select_vals = cb_obj.value;
        let state_col = filters_state.data[filter_col];
        for (let i = 0; i < state_col.length; i++) {
            if (i < select_vals.length) {
                state_col[i] = select_vals[i];
            } else {
                state_col[i] = '';
            }
        }
        filters_state.properties.data.change.emit();
        """)
    )
    return multi_select
Exemple #2
0
    def generate_selection(self):
        devices = self.network.registered_devices
        selectors = []
        _cache = []

        for device in devices:
            try:
                _cache = self._peristent_widget_choices[device.properties.name]
            except KeyError:
                pass
            options = list(device.points_name)
            options.extend(list(device.trendlogs_names))
            mc = MultiChoice(value=_cache,
                             options=options,
                             title=device.properties.name)
            mc.js_on_change(
                "value",
                CustomJS(code="""
                console.log('multi_choice: value=' + this.value, this.toString())
                """),
            )

            selectors.append(mc)
        return selectors
Exemple #3
0
    "menu_item_click",
    CustomJS(code="console.log('dropdown: ' + this.item, this.toString())"))

# Toggle button GUI
toggle = Toggle(label="Button", button_type="success")
toggle.js_on_click(
    CustomJS(code="""
    console.log('toggle: active=' + this.active, this.toString())
"""))

# choice menu GUI
OPTIONS = [str(i) for i in range(20)]
multi_choice = MultiChoice(value=["foo", "baz"], options=OPTIONS)
multi_choice.js_on_change(
    "value",
    CustomJS(code="""
    console.log('multi_choice: value=' + this.value, this.toString())
"""))

# # SELECT menu GUI
# selectoptions = ["Postive tested on Covid-19 virus", "Negative tested on Covid-19 virus", "Show both"]
# resultSelect = Select(title="What to show", options=selectoptions)

# TOOL BUTTON CALLBACKS -----------------------------------------------------------------------------------------------
# Test button GUI
lab = "Click me!"
but = Button(label=lab)


def callback_button1(
):  # simple test callback -> changes lable on button and reports a click to the console
Exemple #4
0
def Persistence_EM_Matrix():
    ### ------------ read files ------------
    
    final = pd.read_csv('./data/App_data/AQ_EM_tse_final.csv',encoding='utf-8')
    profit = pd.read_csv('./data/App_data/AQ_EM_tse_final_profibility_1.csv',encoding='utf-8')
    profit['company_name'] = profit.company.astype(str)+" "+profit.company_abbreviation
    #此檔案中放的為dict, key為用途及名稱,value為list
    with open('app_lists.json','r')as f: 
        app_lists = json.load(f)
    with open('smallco.json','r')as f: 
        smallco_index = json.load(f)
        
    ### ------------ 左側的選項 ------------

    year = Select(title='Year:',value='200812',
                        options=list(final.yyyymm.drop_duplicates().sort_values().astype(str)))

    industry = Select(title='Industry:',value='水泥工業',
                          options = list(profit.tse_industry_name.drop_duplicates())+['All Sectors'])

    index_factor = Select(title='Compared Market Index:',value='TWN50',options=["TWN50", "TM100","TF001"])

    company_list = list((profit.query("yyyymm==200812 & tse_industry_name=='水泥工業'").company_name.astype(str)))

    company_code = Select(title='Company Code: ',value='',options=['']+company_list)

    persistence = Select(title='Persistence:',value='ebit_slope_standard',
                         options= app_lists['options_persistence'])

    EM = Select(title='EM:',value='Jones_model_measure',options=app_lists['options_EM'])

    profit_measure = Select(title='Profit Measure:',value='ROA_ebi',
                            options=app_lists['options_profit_measure'])

    Persistence_percent = RangeSlider(start=0, end=100,value=(20,40), step=1, title="Persistence % :")
    EM_percent = RangeSlider(start=0, end=100,value=(20,40), step=1, title="EM %:")

    #根據選擇日期、產業更新公司列表選項
    ###############################################################################
    def update_company_list(attr,old,new):
        selected_year = year.value
        selected_industry = industry.value
        if selected_industry !='All Sectors':
            company_list = list((profit.query("yyyymm==@selected_year & tse_industry_name==@selected_industry").\
                                 company_name.sort_values().astype(str)))
            #前面加入空値,代表沒有選公司
            company_code.options = ['']+company_list
            #default 為空値
            company_code.value = ''
        else:
            company_list = list((profit.query("yyyymm==@selected_year").\
                            company_name.sort_values().astype(str)))
            #前面加入空値,代表沒有選公司
            company_code.options = ['']+company_list
            #default 為空値
            company_code.value = ''

    #選出畫圖的資料
    ###############################################################################
    def get_plot_data():
        selected_year=year.value
        selected_industry = industry.value
        selected_index_factor = index_factor.value
        selected_Persistence = persistence.value
        selected_EM = EM.value
        selected_profit_measure = profit_measure.value
        if selected_industry !='All Sectors':
            data = profit.query('yyyymm == @selected_year & tse_industry_name  == @selected_industry')
        else :
            data = profit.query('yyyymm == @selected_year')
        #依據日期、產業選擇
        data = data[(data[selected_Persistence].notna()) & (data[selected_EM].notna())]
        #因為有可能選擇的資料也是之後要保留的資料,因此先備份,以免在rename後找不到資料
        origin_data = [selected_Persistence,selected_EM,selected_profit_measure]
        origin = data[origin_data]
        #重新命名,在ColumnDataSource中較好使用
        data.rename(columns={selected_Persistence:'Persistence',selected_EM:'EM',selected_index_factor:'index_factor',
                             selected_profit_measure:'profit_measure'} , inplace=True)
        for i in origin_data:
            data[i] = origin[i]
        data['Persistence'] = data.Persistence.apply(lambda x:value_transfrom(x,selected_Persistence))
        data['EM'] = data.EM.apply(lambda x:value_transfrom(x,selected_EM))
        data['color'] = data['index_factor'].apply(lambda x:'green' if x=='Y' else 'blue')
        data['color'] = data.apply(lambda x:'red' if str(x.company) in smallco_index['2020'] else x.color, 1)

        profit_min = data['profit_measure'].min()
        profit_range = data['profit_measure'].max()-data['profit_measure'].min()
        data['profit_score'] = data['profit_measure'].apply(lambda x:((x-profit_min)/profit_range)*25+5\
                                                            if profit_range!=0 else 30 if x==1 else 5)
        table_data = data[app_lists['select_stock_picking_table_column']]
        data_for_source = data.fillna('--')
        if company_code.value!='':
            data_for_source['text'] = data_for_source['company'].apply(lambda x:'.Here' if x==int(company_code.value[:4])else '')
        else :
            data_for_source['text']=''
        data_for_source = data_for_source[~data_for_source.isin([np.nan, np.inf, -np.inf]).any(1)]
        if company_code.value!='':
            select_co = int(company_code.value[:4])
            data_for_source['select_p'] = data.query('company==@select_co')['Persistence'].to_list()[0]
            data_for_source['select_e'] = data.query('company==@select_co')['EM'].to_list()[0]
        else :
            data_for_source['select_p'] = np.nan
            data_for_source['select_e'] = np.nan

        plot_source = ColumnDataSource(data_for_source)
        return (plot_source,table_data)
    def get_stock_picking_table_data(table_data):
        df = table_data
        Persistence_top = df.Persistence.quantile(Persistence_percent.value[1]/100)
        Persistence_low = df.Persistence.quantile(Persistence_percent.value[0]/100)
        EM_top = df.EM.quantile(EM_percent.value[1]/100)
        EM_low = df.EM.quantile(EM_percent.value[0]/100)
        df = df.query('Persistence <= @Persistence_top & Persistence >= @Persistence_low & EM <= @EM_top & EM >= @EM_low')
        df = df.applymap(lambda x:round(x,2) if type(x)==float else x)
        stock_picking_table_co_choice.options = (df.company.astype(str)+' '+df.company_abbreviation).sort_values().to_list()
        stock_picking_table_co_num.text = f'Total: {df.shape[0]} company'
        return ColumnDataSource(df)

    def get_stock_return_table_2_data():
        selected_year=year.value
        selected_index_factor = index_factor.value
        df = profit.rename(columns={selected_index_factor:'index_factor'})
        df = df.query('yyyymm == @selected_year & index_factor=="Y"')
        return ColumnDataSource(df)

    def get_stock_return_table_3_data(stock_picking_table_source,stock_return_table_2_source):
        if stock_picking_table_source.data['yearly_return'].size ==0 :
            stock_average = [' ']
        else : stock_average = [round(np.nanmean(stock_picking_table_source.data['yearly_return']),4)]

        if stock_return_table_2_source.data['yearly_return'].size ==0 :
            etf_average = [' ']
        else : etf_average = [round(np.nanmean(stock_return_table_2_source.data['yearly_return']),4)]

        return ColumnDataSource(data={'Stock Picking Return (Equally Weighted)':stock_average,
                                      "ETF Return (Equally Weighted)" :etf_average 
                                      })
    def get_matrix_plot_data():
        selected_year=year.value
        df = profit.query('yyyymm == @selected_year')
        df = df[app_lists['options_persistence']+app_lists['options_EM']].corr()
        df = df.apply(lambda x:round(x,2))
        return ColumnDataSource(df)
    ###################################################
    # 製作圖、表  
    def make_scatter_plot(plot_source):
        hover = HoverTool( names=['circle'],
                            tooltips=[('Company Abbreviation :','@company_abbreviation'),
                                        ('Company Code :','@company'),
                                        ('Persistence','@Persistence'),
                                        ('EM :','@EM'),('ROA (EBI) :','@ROA_ebi'),
                                        ('EPS :','@eps'),('ROE_b :','@ROE_b'),
                                        ('Diluted EPS :','@eps_diluted'),('Yearly Return','@yearly_return')]
                         )
        plot = figure(plot_height=500, plot_width=800,
                          tools = ['box_zoom','reset',hover],
                          x_axis_label='Persistence (Log Transformed)',
                          y_axis_label='EM (Log Transformed)', 
                          toolbar_location="right"
                     )
        plot.circle(x="Persistence", y="EM", source=plot_source,color= 'color',size='profit_score', name='circle',
                    line_color=None,alpha=0.5)
#         plot.text('Persistence','EM','text',source=plot_source,color='red',text_font_style='bold',text_font_size='20pt')
        plot.asterisk('select_p','select_e',source=plot_source,color='red',size=20)
        plot.toolbar.active_drag = None
        return plot
    def make_stock_picking_table(stock_picking_table_source):
        columns = []
        for colnames in stock_picking_table_source.data.keys():
            if colnames !='index':
                columns.append(TableColumn(field=colnames, title=colnames, width=6*len(colnames)))
        stock_picking_table = DataTable(source=stock_picking_table_source, columns=columns, width=4000, height = 500)
        return (stock_picking_table)

    def make_stock_return_table_1(stock_picking_table_source):
        columns = []
        for colnames in ['tse_industry_name','company','company_abbreviation','index_factor','yearly_return']:
            columns.append(TableColumn(field=colnames, title=colnames, width=6*len(colnames)))
        stock_return_table_1 = DataTable(source=stock_picking_table_source, columns=columns, height = 500)
        return (stock_return_table_1)
    def make_stock_return_table_2(stock_return_table_2_source):
        columns = []
        for colnames in ['tse_industry_name','company','company_abbreviation','index_factor','yearly_return']:
            columns.append(TableColumn(field=colnames, title=colnames, width=6*len(colnames)))
        stock_return_table_2 = DataTable(source=stock_return_table_2_source, columns=columns, height = 500)
        return (stock_return_table_2)

    def make_stock_return_table_3(stock_return_table_3_source): 
        columns = []
        for colnames in stock_return_table_3_source.data.keys():
            if colnames !='index':
                columns.append(TableColumn(field=colnames, title=colnames, width=6*len(colnames)))
        stock_return_table_3 = DataTable(source=stock_return_table_3_source, columns=columns)
        return (stock_return_table_3)

    def make_matrix_plot(matrix_plot_source):
        columns = []
        for colnames in matrix_plot_source.data.keys():
            if colnames =='index':
                columns.append(TableColumn(field=colnames, title=' ', width=200))
            else:
                columns.append(TableColumn(field=colnames, title=colnames, width=6*len(colnames)))
        matrix_plot = DataTable(source=matrix_plot_source, columns=columns, index_position=None, width = 2500, height=300)
        return (matrix_plot)
    ###################################################
    # 更新 
    def update(attr,old,new):
        stock_picking_table_co_choice.value = []
        new_plot_source,new_table_data=get_plot_data()
        plot_source.data.update(new_plot_source.data)


        new_stock_picking_table_source = get_stock_picking_table_data(new_table_data)
        stock_picking_table_source.data.update(new_stock_picking_table_source.data)

        new_stock_return_table_2_source = get_stock_return_table_2_data()
        stock_return_table_2_source.data.update(new_stock_return_table_2_source.data)

        new_stock_return_table_3_source = get_stock_return_table_3_data(new_stock_picking_table_source,new_stock_return_table_2_source)
        stock_return_table_3_source.data.update(new_stock_return_table_3_source.data)

        new_matrix_plot_source = get_matrix_plot_data()
        matrix_plot_source.data.update(new_matrix_plot_source.data)
    def update_stock_picking(attr,old,new):
        
        pick_list = list(map(lambda x:x[:4],stock_picking_table_co_choice.value))
        new_plot_source,new_table_data=get_plot_data()
        new_stock_picking_table_source = get_stock_picking_table_data(new_table_data)
        df = pd.DataFrame(new_stock_picking_table_source.data).iloc[:,1:]
        if len(pick_list)==0:
            df = df
        else:
            df = df.query('company in @pick_list')
        stock_picking_table_source.data.update(ColumnDataSource(df).data)
        stock_picking_table_co_num.text = f'Total: {df.shape[0]} company'
            

    ###################################################
    # initial 

    plot_source,table_data = get_plot_data()
    plot = make_scatter_plot(plot_source)
    plot_explain = Div(text =
                       '''
                       <span style="padding-left:20px">顏色(綠色): 該公司在該年,有被列在所選的Compared Market Index中 <br/>
                       <span style="padding-left:20px">顏色(紅色): 該公司在該年,有被列在中小型成分股中 <br/>
                       <span style="padding-left:20px">大小: 圈圈越大,代表該公司Profit Measure越大
                       ''')
    tab1 = Panel(child=column(Spacer(height=35), plot, Spacer(height=20), plot_explain), title='Persistence EM Matrix')

    
    stock_picking_table_co_choice = MultiChoice(title = 'select_company:', value=[], options=[], placeholder = '選擇想看的公司')
    stock_picking_table_co_choice.js_on_change("value", CustomJS(code="""
        console.log('multi_choice: value=' + this.value, this.toString())
    """))
    stock_picking_table_co_num = Div(text ='Total:   company')
    stock_picking_table_source = get_stock_picking_table_data(table_data)
    stock_picking_table = make_stock_picking_table(stock_picking_table_source)
    tab2 = Panel(child=column(stock_picking_table_co_num, stock_picking_table, stock_picking_table_co_choice), title='Stock Picking Table')

    div1 = Div(text ='Table 1: The next year return of stocks from the matrix')
    stock_return_table_1 = make_stock_return_table_1(stock_picking_table_source)
    div2 = Div(text ='Table 2: The next year return of stocks in ETF')
    stock_return_table_2_source = get_stock_return_table_2_data()
    stock_return_table_2 = make_stock_return_table_2(stock_return_table_2_source)
    div3 = Div(text ='Table 3: The next year return of equally weighted portfolios')
    stock_return_table_3_source = get_stock_return_table_3_data(stock_picking_table_source,stock_return_table_2_source)
    stock_return_table_3 = make_stock_return_table_3(stock_return_table_3_source)
    tab3 = Panel(child=row([column(div1,stock_return_table_1),
                            column(div2,stock_return_table_2),
                            column(div3,stock_return_table_3)]),
                 title='Stock Return Table')

    matrix_plot_source = get_matrix_plot_data()
    matrix_plot = make_matrix_plot(matrix_plot_source)
    matrix_plot_explain = Div(text = 
        '''
        Persistence: <br/>
        <span style="padding-left:50px">ebit_slope_standard <br/>
        <span style="padding-left:50px">operating_slope_standard <br/>
        <span style="padding-left:50px">yoy_ebit_standard <br/>
        <span style="padding-left:50px">yoy_operating_standard <br/>
        <br/><br/>
        EM: <br/>
        <span style="padding-left:50px">Jones_model_measure <br/>
        <span style="padding-left:50px">Modified_Jones_model_measure <br/>
        <span style="padding-left:50px">Performance_matching_measure <br/>
        <span style="padding-left:50px">opacity_Jones_model_measure <br/>
        <span style="padding-left:50px">opacity_modified_Jones_model_measure <br/>
        <span style="padding-left:50px">opacity_performance_matching <br/>
        ''')
    tab4 = Panel(child=column(matrix_plot,row(Spacer(width=20), matrix_plot_explain)), title='Correlation Matrix of Persistence & EM')

    tabs = Tabs(tabs=[tab1,tab2,tab3,tab4])

    ###################################################
    # input change
    year.on_change('value', update, update_company_list)
    industry.on_change('value', update, update_company_list)
    index_factor.on_change('value', update)
    company_code.on_change('value', update)
    persistence.on_change('value', update)
    EM.on_change('value', update)
    profit_measure.on_change('value', update)
    Persistence_percent.on_change('value', update)
    EM_percent.on_change('value', update)
    stock_picking_table_co_choice.on_change('value', update_stock_picking)

    ###################################################
    # layout
    div_title = Div(text ='Persistence & EM Matrix',style={'font-size': '200%', 'color': 'blue'})
    inputs = column(div_title,year, industry, index_factor, company_code,persistence,EM,profit_measure,
                             Persistence_percent,EM_percent, background='gainsboro')
    final_layout = row(inputs, tabs, width=1200)
    return Panel(child = column(Spacer(height = 35), final_layout), title = 'Persistence & EM 概況')
def multilinePlot(dataset_id, columnName):
    log = DatasetManager.query.get_or_404(dataset_id)
    datasetName = log.datasetName
    datasetSqlName = log.datasetSqlName
    df = pd.read_sql_table(datasetSqlName, db.engine)
    # prepare some data
    x = df["index"]
    # create a new plot with a title and axis labels
    p = figure(
        title="Dataset Name: " + datasetName,
        x_axis_label="Index",
        y_axis_label="y",
        sizing_mode="fixed",
        plot_width=1100,
        plot_height=400,
    )

    # Initialize source to x=[x] and y=[x]
    # Note:
    # Multi-line plots take an array as x's and y's
    # The x and y arrays must be the same length
    initialColumnName = columnName
    y = df[columnName]
    source = ColumnDataSource(data=dict(x=[x], y=[y]))
    df_source = ColumnDataSource(data=dict(df))
    p.multi_line("x", "y", source=source)

    # Create menu and options with name of data columns with numerical data
    columns = df.columns.to_list()
    menu = []
    options = []
    for columnName in columns:
        # if df[columnName].dtype == np.float64 or df[columnName].dtype == np.int64:
        if is_numeric_dtype(df[columnName]):
            # Menu is a list of tuples of name/value pairs for dropdown widget
            menu.append((columnName, columnName))
            # Option is a list of column names for multi-select widget
            options.append(columnName)

    # Create dropdown widget
    dropdown = Dropdown(label="Select Column",
                        button_type="primary",
                        menu=menu,
                        width_policy="min")
    # Create multi-select widget
    multi_choice = MultiChoice(value=[initialColumnName],
                               options=options,
                               title="Select Columns")

    # Define JS callback to change column to plot
    callback_dropdown = CustomJS(
        args=dict(source=source, df_source=df_source),
        code="""
        // Initialize x and y arrays
        var data = source.data;
        var x = data['x'];
        // console.log(' x=' + x);
        var y = data['y'];
        // console.log('y=' + y);

        // Get dataframe
        var df_data = df_source.data;

        // Set y array to selected value
        y[0] = df_data[this.item];

        // Update plot with new x,y source data
        source.change.emit();
        """,
    )
    callback_multi_select = CustomJS(
        args=dict(source=source, df_source=df_source),
        code="""
        // Initialize x and y arrays
        var data = source.data;
        var x = data['x'];
        var y = data['y'];
        x.length = 0;
        y.length = 0;
        // console.log(' x=' + x);
        // console.log('x.length=' + x.length);
        // console.log('y=' + y);
        // console.log('y.length=' + y.length);

        // Get dataframe
        var df_data = df_source.data;

        // Get value of multi-select widget
        // console.log('multi_select: ' + this.value, this.value.toString());
        var array = this.value;
        

        // Iterate through multi-select values and update x,y arrays with selected values
        var array_iterator = array.values();
        let next_value = array_iterator.next();
        while (!next_value.done) {
        // console.log(next_value.value);
        x.push(df_data['index']);
        y.push(df_data[next_value.value]);
        next_value = array_iterator.next();
        }
        // console.log('y=' + y);
        // console.log('y.length=' + y.length);
        // console.log('x.length=' + x.length);

        // Update plot with new x,y source data
        source.change.emit();
        """,
    )

    # Define javascript events to trigger callbacks
    dropdown.js_on_event(
        "menu_item_click",
        callback_dropdown,
    )

    multi_choice.js_on_change(
        "value",
        callback_multi_select,
    )

    layout = column(multi_choice, p)
    return layout
Exemple #6
0
def one_filter(plot, point_source, filter_col):
    # Remove (FX) from column name; probaby temporary
    title = re.sub(r'\s*[(]F[0-9]+[)]\s*', '', filter_col)

    full_source = GeoJSONDataSource(geojson=point_source.geojson)

    # Extract options from values in the data:
    options = [
        f['properties'][filter_col]
        for f in json.loads(point_source.geojson)['features']
    ]
    # Some values are comma-separated lists; split and unpack, dropping None.
    options = [
        opt.strip() for opt_list in options if opt_list is not None
        for opt in opt_list.split(',')
    ]
    # Deduplicate and turn into name-value pairs, as required by MultiSelect.
    options = [(opt, ) * 2 for opt in sorted(set(options))]
    multi_select = MultiChoice(title=title,
                               width=int(plot.plot_width / 1.5),
                               height=int(plot.plot_height / 8),
                               max_items=4,
                               options=options)

    callback = CustomJS(args=dict(source=point_source,
                                  multi_select=multi_select,
                                  full_source=full_source,
                                  filter_col=filter_col),
                        code="""

        function filter(select_vals, source, filter, full_source) {
            for (const [key, value] of Object.entries(source.data)) {
                while (value.length > 0) {
                    value.pop();
                }
            }
            for (const [key, value] of Object.entries(full_source.data)) {
                for (let i = 0; i < value.length; i++) {
                    if (isIncluded(filter, select_vals, i, full_source)) {
                        source.data[key].push(value[i]);
                    }
                }
            }
        }

        function isIncluded(filter, select_vals, index, full_source) {
            // Slow -- O(i * j) -- but i and j never get much larger than 10
            for (var i = 0; i < select_vals.length; i++) {
                let vals = full_source.data[filter][index];
                vals = vals ? vals.split(',').map(s => s.trim()) : [];
                for (let j = 0; j < vals.length; j++) {
                    if (vals[j] == select_vals[i]) {
                        return true;
                    }
                }
            }
            return false;
        }

        var select_vals = cb_obj.value;
        filter(select_vals, source, filter_col, full_source);
        source.change.emit();
        """)
    multi_select.js_on_change('value', callback)
    return multi_select