Advertisement
Guest User

Untitled

a guest
Feb 20th, 2020
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.96 KB | None | 0 0
  1. ##!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3.  
  4. import dash
  5. import dash_core_components as dcc
  6. import dash_html_components as html
  7. from dash.dependencies import Input, Output
  8. from datetime import datetime as dt
  9.  
  10. import plotly.graph_objs as go
  11.  
  12. import pandas as pd
  13.  
  14. from sqlalchemy import create_engine
  15.  
  16. engine = create_engine('sqlite:////db/zen.db', echo = False)
  17.  
  18. db_config = {'user': 'my_user',
  19.             'pwd': 'my_user_password',
  20.             'host': 'localhost',
  21.             'port': 5432,
  22.             'db': 'zen'}
  23. engine = create_engine('postgresql://{}:{}@{}:{}/{}'.format(db_config['user'],
  24.                                                            db_config['pwd'],
  25.                                                            db_config['host'],
  26.                                                            db_config['port'],
  27.                                                            db_config['db']))
  28.  
  29. #получаем сырые данные
  30. query1 = '''
  31.            SELECT *
  32.            FROM dash_visits
  33.        '''
  34. dash_visits = pd.io.sql.read_sql(query1, con = engine)
  35. dash_visits['dt'] = pd.to_datetime(dash_visits['dt'])
  36.  
  37. query2 = '''
  38.            SELECT *
  39.            FROM dash_engagement
  40.        '''
  41. dash_engagement = pd.io.sql.read_sql(query2, con = engine)
  42. dash_engagement['dt'] = pd.to_datetime(dash_engagement['dt'])
  43.  
  44.  
  45. note = '''
  46.          Этот дашборд показывает взаимодействие пользователей с карточками Яндекс.Дзен.
  47.        
  48.          Используйте выбор интервала даты события, тем карточек и возрастной категории пользователей для управления дашбордом.
  49.       '''
  50. #задаём лейаут
  51. external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
  52. app = dash.Dash(__name__, external_stylesheets = external_stylesheets)
  53. app.layout = html.Div(children=[  
  54.  
  55.     #заголовок
  56.     html.H1(children = 'Дашборд для Яндекс.Дзен'),    
  57.  
  58.     html.Br(),  
  59.     html.Label(note),
  60.  
  61.     html.Br(),        
  62.  
  63.     html.Div([
  64.         html.Div([
  65.             html.Div([
  66.             #выбор временного периода
  67.                 html.Label('Фильтр даты'),
  68.                     dcc.DatePickerRange(
  69.                         start_date = dash_visits['dt'].dt.date.min(),
  70.                         end_date = dash_visits['dt'].dt.date.max(),
  71.                         display_format = 'YYYY-MM-DD',
  72.                         id = 'dt_selector',
  73.                         ),
  74.                     ], className = 'row container-display'),          
  75.        
  76.             html.Div([
  77.             #выбор возраста
  78.                 html.Label('Фильтр возрастных категорий'),
  79.                     dcc.Dropdown(
  80.                         options = [{'label': x, 'value': x} for x in dash_visits['age_segment'].unique()],
  81.                         value = dash_visits['age_segment'].unique(),
  82.                         multi = True,
  83.                         id = 'age-dropdown',
  84.                         ),
  85.                     ], className = 'row container-display'),
  86.             ], className = 'six columns'
  87.             ),
  88.        
  89.             html.Div([
  90.             #выбор тем карточек    
  91.                 html.Label('Фильтр тем карточек'),
  92.                     dcc.Dropdown(
  93.                         options = [{'label': x, 'value': x} for x in dash_visits['item_topic'].unique()],
  94.                         value = dash_visits['item_topic'].unique(),
  95.                         multi = True,
  96.                         id = 'item-topic-dropdown',
  97.                         style = {'height':'50%'}
  98.                         ),
  99.                 ], className = 'six columns'),
  100.             ], className = 'row'),
  101.    
  102.     html.Div([
  103.         html.Div([        
  104.             html.Label('История событий по темам карточек'),
  105.             dcc.Graph(
  106.                 id = 'history-absolute-visits',
  107.                 style = {'height': '50vw'},
  108.                 ),  
  109.             ], className = 'six columns'),  
  110.  
  111.         html.Div([        
  112.             html.Label('События по темам источников'),
  113.             dcc.Graph(
  114.                 id = 'pie-visits',
  115.                 style = {'height': '25vw'},
  116.             ),  
  117.             html.Label('Средняя глубина взаимодействия'),
  118.             dcc.Graph(
  119.                 id = 'engagement-graph',
  120.                 style = {'height': '25vw'},
  121.             ),  
  122.             ], className = 'six columns')            
  123.         ], className = 'row')
  124. ])
  125.  
  126. #описываем логику дашборда
  127. @app.callback(
  128.     [Output('history-absolute-visits', 'figure'),
  129.     Output('pie-visits', 'figure'),
  130.     Output('engagement-graph', 'figure')],
  131.     [Input('item-topic-dropdown', 'value'),
  132.     Input('age-dropdown', 'value'),
  133.     Input('dt_selector', 'start_date'),
  134.     Input('dt_selector', 'end_date'),
  135.     ])
  136.  
  137. def update_figures(selected_item_topics, selected_ages, start_date, end_date):
  138.  
  139.     start_date = dt.strptime(start_date, '%Y-%m-%d')
  140.     end_date = dt.strptime(end_date, '%Y-%m-%d')
  141.  
  142.     #применяем фильтрацию
  143.     visits_filtered = dash_visits.query('item_topic in @selected_item_topics')
  144.     visits_filtered = visits_filtered.query('dt >= @start_date and dt <= @end_date')
  145.     visits_filtered = visits_filtered.query('age_segment in @selected_ages')
  146.  
  147.    
  148.     engagement_filtered = dash_engagement.query('item_topic in @selected_item_topics')
  149.     engagement_filtered = engagement_filtered.query('dt >= @start_date and dt <= @end_date')
  150.     engagement_filtered = engagement_filtered.query('age_segment in @selected_ages')
  151.    
  152.     #данные для графиков
  153.     visits_by_item_topic = (visits_filtered.groupby(['item_topic','dt'])
  154.                                            .agg({'visits' : 'sum'})
  155.                                            .sort_values(by = 'visits', ascending = False)
  156.                                            .reset_index())
  157.                                
  158.     visits_by_source_topic = (visits_filtered.groupby('source_topic')
  159.                                              .agg({'visits' : 'sum'})
  160.                                              .reset_index())
  161.  
  162.     engagement = (engagement_filtered.groupby('event')
  163.                                      .agg({'unique_users' : 'mean'})
  164.                                      .rename(columns = {'unique_users' : 'avg_unique_users'})
  165.                                      .sort_values(by = 'avg_unique_users', ascending = False)
  166.                                      .reset_index())
  167.    
  168.     data_item_topic_dropdown = []
  169.    
  170.     #график истории событий по темам карточек
  171.     for item in visits_by_item_topic['item_topic'].unique():
  172.         current = visits_by_item_topic[visits_by_item_topic['item_topic'] == item]
  173.         data_item_topic_dropdown += [go.Scatter(x = current['dt'],
  174.                                    y = current['visits'],
  175.                                    mode = 'lines',
  176.                                    stackgroup = 'one',
  177.                                    name = item)
  178.                         ]
  179.                        
  180.     #график разбивки событий по темам источников
  181.     data_pie_source_topic = [go.Pie(labels = visits_by_source_topic['source_topic'],
  182.                                     values = visits_by_source_topic['visits'])
  183.  
  184.                         ]
  185.                          
  186.     #график средней глубины взаимодействия
  187.     data_engagement_graph = [go.Bar(x = engagement['event'],
  188.                                    y = engagement['avg_unique_users'],
  189.                                    name = 'Среднее количество пользователей')
  190.                         ]
  191.    
  192.    
  193.  
  194.     return (
  195.             #график item-topic
  196.             {
  197.                 'data': data_item_topic_dropdown,
  198.                 'layout': go.Layout(xaxis = {'title': 'Время'},
  199.                                     yaxis = {'title': 'Количество событий'})
  200.             },    
  201.            
  202.             #график pie-visits
  203.             {
  204.                 'data': data_pie_source_topic,
  205.                 'layout': go.Layout()
  206.             },
  207.            
  208.             #график engagement-graph
  209.             {
  210.                 'data': data_engagement_graph,
  211.                 'layout': go.Layout(xaxis = {'title': 'Тип cобытия'},
  212.                                     yaxis = {'title': 'Среднее число пользователей'},
  213.                                     hovermode = 'closest')
  214.              },
  215.          )            
  216.  
  217. if __name__ == '__main__':
  218.     app.run_server(debug=True, host='0.0.0.0')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement