Exemplo n.º 1
0
        dcc.Graph(id='fig'),
        dcc.Location(id='url'),
        html.Div(id='empty', style={'display': 'none'}),
    ],
    style={
        'position': 'absolute',
        'top': '15vh',
        'left': '10vw',
        'width': '80vw',
        'height': '60vh'
    })

app.clientside_callback("""
    function(path) {
        return String(window.innerWidth) + ',' + String(window.innerHeight);
    }    
    """,
                        Output('empty', 'children'),
                        [Input('url', 'pathname')],
                        prevent_initial_call=True)


@app.callback(Output('fig', 'figure'), [Input('empty', 'children')],
              prevent_initial_call=True)
def draw_on_reload(c):
    plot_data = {}

    for team in teams:
        team_data = SignupData.objects.filter(team=team)
        d = datetime.date(2020, 9, 20)
        accd = []
        while d <= datetime.date.today():
Exemplo n.º 2
0
            ],
                    className='bar_card')
        ],
                md=9)
    ],
            className=''),
    dcc.Location(id='url'),
    html.Div('', id='empty', style={'display': 'none'})
],
                      className='dashboard_container',
                      id='team_container')

app.clientside_callback(
    """
    function(path) {
        console.log(path)
        return path+',' + String(window.innerWidth) + ',' + String(window.innerHeight);
    }
    """, Output('empty', 'children'), [Input('url', 'pathname')])


@app.callback([
    Output('team_thumbnail', 'children'),
    Output('team_datatable', 'children'),
    Output('team_map', 'figure'),
    Output('bar1', 'children'),
    Output('bar2', 'children'),
    Output('bar3', 'children'),
], [Input('empty', 'children')],
              prevent_initial_call=True)
def on_page_load(init_info):
Exemplo n.º 3
0
Arquivo: app.py Projeto: sgvolpe/river
class AnalysisApp:
    def __init__(self,
                 dfs_path=os.path.join('static', 'dfs'),
                 title='Analysis Dashboard',
                 app_name='app',
                 callback_side='backend'):
        """
            callback_side='client' is not implemented for multiple outputs yet in dash
        """

        if DEBUG: print('AnalysisApp init')
        self.dfs_path = dfs_path
        self.title = title
        self.callback_side = callback_side
        self.app_name = app_name

        self.template = self.CHART_FONT = self.opacity = None
        self.get_style()

        # Create Dahs App
        self.app = DjangoDash('analysis_app',
                              add_bootstrap_links=True,
                              suppress_callback_exceptions=True)
        # self.app.css.append_css({'external_url': 'https://codepen.io/amyoshino/pen/jzXypZ.css'})
        # external_js = ["https://code.jquery.com/jquery-3.2.1.min.js", "https://codepen.io/bcd/pen/YaXojL.js"]
        # for js in external_js: self.app.scripts.append_script({"external_url": js})

        # Instantiate components empty
        self.input_components, self.div_charts, self.div_tables, self.function_outputs = [], [], [], []
        self.main_inputs, self.inputs_as_output, self.function_inputs, self.parameter_inputs = [], [], [], []

        # Read Data
        self.read_data()
        if DEBUG: print(' -> Data Read')

        # Initialize Components
        self.read_input_configuration()
        self.create_input_components()
        self.create_output_components()
        self.update_inputs()
        # self.update_output()

        # Create App Layout
        self.app.layout = html.Div([
            html.H2(self.title),
            dcc.Dropdown(id='test',
                         options=[{
                             'label': 'chart1',
                             'value': 'chart1'
                         }, {
                             'label': 'chart2',
                             'value': 'chart2'
                         }, {
                             'label': 'San Francisco',
                             'value': 'SF'
                         }],
                         placeholder="Select a city",
                         multi=True),
            self.input_components,
            self.div_charts,
            self.div_tables,
        ],
                                   className="principal")
        # self.app.config.suppress_callback_exceptions = True

        # Cache
        # self.cache = Cache(self.app.server, config={
        #    # try 'filesystem' if you don't want to setup redis
        #    'CACHE_TYPE': 'filesystem',
        #    'CACHE_DIR': 'cache-directory'
        # })
        # self.cache.memoize(timeout=5)(self.update_output)

        # Associate callbacks
        if self.callback_side == 'backend':
            self.app.callback(
                inputs=self.main_inputs,
                output=self.inputs_as_output,
            )(self.update_inputs)
            self.app.callback(
                inputs=self.function_inputs +
                [Input('correlation_chart', 'selectedData')],
                output=self.function_outputs,
            )(self.update_output)
            self.app.callback(output=[
                Output('chart1', component_property='style'),
                Output('chart2', component_property='style')
            ],
                              inputs=[Input('test',
                                            'value')])(self.hide_charts)

        elif self.callback_side == 'client':
            ip = ','.join(self.parameter_inputs)

            self.app.clientside_callback(
                f"""
                function({ip}) {{
                    return update_inputs({ip});
                }}
                """,
                output=self.inputs_as_output,
                inputs=self.main_inputs,
            )  # (self.update_inputs)

            self.app.clientside_callback(
                f"""
                    function({ip}) {{
                         return update_output({ip});
                    }}
                """,
                output=self.function_outputs,
                inputs=self.function_inputs,
            )  # (self.update_output)

        if DEBUG: print(' -> Layout & Callbacks Ready')

    def hide_charts(self, show_charts):
        print('@@@@@@@@@@@@@@@@')
        print(show_charts)
        retorno = []
        for chart_name in ['chart1', 'chart2']:
            if chart_name in show_charts:
                retorno.append({'display': 'block'})
            else:
                retorno.append({'display': 'none'})

        return retorno

    def get_style(self):

        conf_path = os.path.join('static', 'analysis_app', 'conf_files',
                                 f'{self.app_name}.txt')
        with open(conf_path) as json_file:
            json_conf = json.load(json_file, encoding='cp1252')

        self.charts = json_conf['charts']
        self.tables = json_conf['tables']
        self.template = json_conf['style']['template']
        self.CHART_FONT = json_conf['style']['chart_font']
        self.opacity = json_conf['style']['opacity']

        if DEBUG: print(' -> Style Ready', self.template)

    @try_catch
    def get_csv(self, df_name='test_df.csv', path='static/dfs/'):
        """
            Returns a pandas dataframe from a csv
        """
        self.df = pd.read_csv(os.path.join(path, df_name))

    @try_catch
    def read_data(self, dataframe_name=None):
        # Read data
        self.dataframes = [df_name for df_name in os.listdir(self.dfs_path)]
        if dataframe_name is None: dataframe_name = self.dataframes[0]
        self.get_csv(dataframe_name)
        self.columns_str = self.df.select_dtypes(include='object').columns
        self.columns_numeric = self.df.select_dtypes(
            include=['float64', 'int']).columns

    @try_catch
    def get_component(self, i, v):
        """
            Generates de dcc component based on the attributes passed
        """
        if v['control_type'] == 'dropdown':
            return html.P(
                dcc.Dropdown(
                    options=[{
                        'label': x,
                        'value': x
                    } for x in v['data']],
                    value=v['data'][0],
                    className=v['className'],
                    id=f'{i}',
                    persistence=True,
                    persistence_type='local',  # local|memory
                    clearable=True,
                    searchable=True,
                    placeholder=f"Select a {i}",
                    disabled=False,
                ))
        elif v['control_type'] == 'slider':
            return html.P(
                dcc.RangeSlider(
                    id=f'{i}',
                    min=v['data']['min'],
                    max=v['data']['max'],
                    step=v['data']['step'],
                    value=v['data']['value'],
                ), )

    @try_catch
    def read_input_configuration(self,
                                 input_f_path=''):  # TODO: read from file
        # Create the Inputs from Configuration
        self.inputs_conf = {
            'dataframe': {
                'property': 'value',
                'control_type': 'dropdown',
                'data': self.dataframes,
                'className': 'col-6',
                'main_control': True
            },
            'categorical': {
                'property': 'value',
                'control_type': 'dropdown',
                'data': self.columns_str,
                'className': 'col-6',
                'main_control': False
            },
            'numerical': {
                'property': 'value',
                'control_type': 'dropdown',
                'data': self.columns_numeric,
                'className': 'col-6',
                'main_control': False
            },
        }

        if DEBUG: print(' -> Input Configuration Ready')

    @try_catch
    def save_input_config(self, input_f_path=''):  # TODO:
        pass

    @try_catch
    def create_input_components(self):
        self.input_components = html.Div(className='row',
                                         id='controls_div',
                                         children=[])
        self.main_inputs, self.inputs_as_output, self.function_inputs = [], [], [
        ]  # Restart Components
        self.parameter_inputs = []
        for i, v in self.inputs_conf.items():
            self.input_components.children.append(
                html.Div(className='col', children=[self.get_component(i,
                                                                       v)]), )

            if v['main_control']:
                self.main_inputs.append(Input(i, v['property']))
            else:
                self.parameter_inputs.append(i)
                self.parameter_inputs.append(f'{i}_selected_data')
                self.function_inputs.append(Input(i, v['property']))
                # self.function_inputs.append(Input(i, 'selectedData'))

                self.inputs_as_output.append(Output(i, 'options'))
                self.inputs_as_output.append(Output(i, v['property']))

        if DEBUG: print(' -> Input Components Ready')

    @try_catch
    def create_output_components(self):
        self.function_outputs = []
        self.div_charts = html.Div(className='row',
                                   id='charts_div',
                                   children=[])

        new_row = "row"
        for chart_name in self.charts:
            self.div_charts.children.append(
                html.Div([
                    html.Div([
                        dcc.Graph(id=chart_name, style={}),
                    ],
                             className="col card",
                             id=f'{chart_name}_div'),
                ],
                         className=f"{new_row}"))
            self.function_outputs.append(Output(chart_name, 'figure'))

        self.div_tables = html.Div(className='row',
                                   id='tables_div',
                                   children=[])

        for table_name in self.tables:
            self.div_tables.children.append(
                html.Div(id=f'{table_name}', className='col card'))
            self.function_outputs.append(Output(table_name, 'children'))

        if DEBUG: print(' -> Output Components Ready')

    @try_catch
    def update_inputs(self,
                      dataframe_name='test_df.csv'):  # self.parameter_inputs
        """ Update the values of the Input Controls """
        self.read_data(dataframe_name=dataframe_name)
        return [{'label': col, 'value': col} for col in self.columns_str], self.columns_str[0], \
               [{'label': col, 'value': col} for col in self.columns_numeric], self.columns_numeric[0]

    @try_catch
    def get_boxplot(self, categorical_column, variable_column, df):
        try:
            names = self.df[categorical_column].unique()
            data = [
                go.Box(  # marker=dict(color=COLORS[provider],
                    opacity=self.opacity,
                    name=name,
                    x=df[df[categorical_column] == name][categorical_column],
                    y=df[df[categorical_column] == name][variable_column])
                for name in names
            ]
            layout = {
                'legend_orientation':
                'h',
                'title':
                go.layout.Title(text=f"Distribution of {variable_column}", ),
                'template':
                self.template
            }
        except Exception as e:
            print(str(e))
            data, layout = [], {}
        return go.Figure(data=data, layout=layout)

    @try_catch
    def get_histogram(self,
                      categorical_column,
                      variable_column,
                      df,
                      x_name='sepal_length',
                      y_name='petal_length'):
        '''try:

            names = df[categorical_column].unique()
            data = [
                dict(
                    type='scatter',
                    mode='markers',
                    x=name_df[x_name],
                    y=name_df[y_name],
                    name=name,
                ) for name_df, name in [(df[df[categorical_column] == name], name) for name in names]
            ]

            layout = {
                'title': go.layout.Title(text=f"{y_name} vs {x_name}", font=CHART_FONT),
                'xaxis': go.layout.XAxis(
                    title=go.layout.xaxis.Title(text=x_name, font=CHART_FONT)),
                'yaxis': go.layout.YAxis(
                    title=go.layout.yaxis.Title(text=y_name, font=CHART_FONT)),
                'template': template,
            }
        except: data, layout = [], {}
        return go.Figure(data=data, layout=layout)'''

        return px.histogram(
            df,
            x=variable_column,
            y=variable_column,
            color=categorical_column,
            marginal="box",
            # or violin, rug
            hover_data=self.df.columns,
            template=self.template)

    @try_catch
    def get_null_map(self, df, columns_numeric):
        layout = {
            'legend_orientation': 'h',
            'title': go.layout.Title(text=f"Null Distribution", ),
            'template': self.template
        }
        return go.Figure(data=go.Heatmap(
            z=self.df[columns_numeric].isnull().astype(int).to_numpy()),
                         layout=layout)

    @try_catch
    def generate_correlation_chart(self, categorical_column, **kwargs):

        index_vals = self.df[categorical_column].astype('category').cat.codes

        fig = go.Figure(data=go.Splom(
            dimensions=[
                dict(label=c, values=self.df[c]) for c in self.columns_numeric
            ],
            text=self.df[categorical_column],
            marker=dict(
                color=index_vals,
                showscale=False,  # colors encode categorical variables
                line_color='white',
                line_width=0.5)))

        fig.update_layout(title='Correlations',
                          template=self.template)  # ,width=600, height=600,
        return fig

    @try_catch
    def generate_outlayers(self, categorical_column):
        # def get_outlayers(self, param='Total Unsuccessful', date=None, dataframe=None):

        D = []
        for category in self.df[categorical_column].unique():
            specific_df = self.df[self.df[categorical_column] == category]
            for feature in self.columns_numeric:
                specific_df['measuring'] = specific_df[feature]

                qv1 = specific_df[feature].quantile(0.25)
                qv3 = specific_df[feature].quantile(0.75)
                qv_limit = 1.5 * (qv3 - qv1)
                un_outliers_mask = (specific_df[feature] > qv3 + qv_limit) | (
                    specific_df[feature] < qv1 - qv_limit)
                un_outliers_data = specific_df[feature][un_outliers_mask]
                un_outliers_name = specific_df[un_outliers_mask]

                if un_outliers_data.shape[0] > 0:
                    for i in [{
                            'feature': feature,
                            'category': category,
                            'value': val
                    } for val in un_outliers_data]:
                        D.append(i)

        return pd.DataFrame(D)

    @try_catch  # categorical_column, variable_column ####
    def update_output(self, categorical_column, variable_column,
                      selected_data):

        if selected_data is None:
            self.selected_df = self.df
        else:
            selected_points = [
                p['pointNumber'] for p in selected_data['points']
            ]
            self.selected_df = self.df[self.df.index.isin(selected_points)]
        print(f'LENGTH OF DATAFRAME: ')
        print(self.selected_df.shape)
        outlayers = self.generate_outlayers(categorical_column)

        kwargs = {
            'categorical_column': categorical_column,
            'variable_column': variable_column,
            'df': self.selected_df
        }

        output_generators = OrderedDict({
            'chart1': {
                'function': self.get_boxplot,
                'kwargs': kwargs
            },
            'chart2': {
                'function': self.get_histogram,
                'kwargs': kwargs
            },
            'correlation_chart': {
                'function': self.generate_correlation_chart,
                'kwargs': kwargs
            },
            'get_null_map': {
                'function': self.get_null_map,
                'kwargs': {
                    'df': self.df,
                    'columns_numeric': self.columns_numeric
                }
            },
            'table1': {
                'function': generate_table_simple,
                'kwargs': {
                    'dataframe': self.df.describe().round(1)
                }
            },
            'outlayers_table': {
                'function': generate_table_simple,
                'kwargs': {
                    'dataframe': outlayers
                }
            },
            'full_Table': {
                'function': generate_table_simple,
                'kwargs': {
                    'dataframe': self.df
                }
            },
        })
        return [
            values['function'](**values['kwargs'])
            for out_name, values in output_generators.items()
            if out_name in self.charts + self.tables
        ]

    @try_catch
    def get_app(self):
        return self.app
Exemplo n.º 4
0
class Graphs:
    def __init__(self,
                 app_name,
                 graph_title,
                 graph_id,
                 slider_id,
                 top_bool,
                 app_input_state_list,
                 graph_color='Crimson',
                 time_scale='12-m',
                 anime_name="default"):
        self.jikan = Jikan()
        self.app_name = app_name
        self.graph_title = graph_title
        self.graph_id = graph_id
        self.slider_id = slider_id
        self.top_bool = top_bool
        self.app_input_state_list = app_input_state_list
        self.graph_color = graph_color
        self.time_scale = time_scale
        self.anime_name = anime_name
        self.app = DjangoDash(app_name,
                              external_stylesheets=external_stylesheets)
        self.app.layout = html.Div([
            html.H1(graph_title),
            #html.Button("Custom export", id="export_table", **{"data-dummy": ""}),
            self.return_graph(
            ),  # dcc.Graph(id=graph_id, animate=True, style={"backgroundColor": "#1a2d46", 'color': '#ffffff'})
            # html.Button("Custom export", id="export_table", **{"data-dummy": ""}),
            # dcc.Slider(
            #     id=slider_id,
            #     marks={i: '{}'.format(i) for i in range(20)},
            #     max=20,
            #     value=2,
            #     step=1,
            #     updatemode='drag',
            #     min=0,
            # ),
        ])

        self.app.clientside_callback(
            """
            function(n_clicks) {
                if (n_clicks > 0)
                    document.querySelector("#topanime a.modebar-btn").click()
                return ""
            }
            """, Output("export_table", "data-dummy"),
            [Input("export_table", "n_clicks")])

        @self.app.callback(Output(graph_id, 'figure'), app_input_state_list)
        def display_value(value):

            trendshow = TrendReq(hl='en-US', tz=360)

            kw_list = []
            if top_bool:
                for k in range(0, 5):
                    kw_list.append(self.get_top_anime_names(k, 'tv'))
            else:
                kw_list.append(self.search_anime(anime_name))
            kw_group = list(zip(*[iter(kw_list)] * 1))
            kw_grplist = [list(x) for x in kw_group]
            dic = {}
            i = 0
            for kw in kw_grplist:
                trendshow.build_payload(kw, timeframe='today 1-w', geo='')
                dic[i] = trendshow.interest_over_time()
                i += 1

            trendframe = pd.concat(dic, axis=1)
            trendframe.columns = trendframe.columns.droplevel(0)
            trendframe = trendframe.drop('isPartial', axis=1)

            trace = [
                go.Scatter(x=trendframe.index, y=trendframe[col], name=col)
                for col in trendframe.columns
            ]
            layout = dict(paper_bgcolor='#27293d',
                          plot_bgcolor='rgba(0,0,0,0)',
                          font=dict(color='white'),
                          showlegend=True)
            return {'data': trace, 'layout': layout}

    def get_top_anime_names(self, rank: int, subtype: str):
        top_anime = self.jikan.top(type='anime', page=1, subtype=subtype)
        time.sleep(0.5)
        return top_anime["top"][rank]["title"]

    def search_anime(self, anime_name):
        search = self.jikan.search('anime', anime_name)
        time.sleep(0.5)
        return search["results"][0]["title"]

    def return_graph(self):
        trendshow = TrendReq(hl='en-US', tz=360)

        kw_list = []
        if self.top_bool:
            for k in range(0, 5):
                kw_list.append(self.get_top_anime_names(k, 'tv'))
        else:
            kw_list.append(self.search_anime(self.anime_name))
        kw_group = list(zip(*[iter(kw_list)] * 1))
        kw_grplist = [list(x) for x in kw_group]
        dic = {}
        i = 0
        for kw in kw_grplist:
            trendshow.build_payload(kw,
                                    timeframe='today ' + self.time_scale,
                                    geo='')
            dic[i] = trendshow.interest_over_time()
            i += 1

        trendframe = pd.concat(dic, axis=1)
        trendframe.columns = trendframe.columns.droplevel(0)
        trendframe = trendframe.drop('isPartial', axis=1)

        fig = {
            'data': [
                go.Scatter(x=trendframe.index,
                           y=trendframe[col],
                           name=col,
                           line=dict(color=self.graph_color))
                for col in trendframe.columns
            ],
            'layout':
            dict(
                #legend=dict(font=dict(color='#7f7f7f')),
                paper_bgcolor='#27293d',
                plot_bgcolor='rgba(0,0,0,0)',
                font=dict(color='white'),
                showlegend=True)
        }

        return dcc.Graph(id=self.graph_id, figure=fig)

    def return_layout(self):
        return self.app.layout