Advertisement
Guest User

Untitled

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