Advertisement
Guest User

Untitled

a guest
Nov 17th, 2019
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.21 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. import numpy as np
  15.  
  16. # задаём данные для отрисовки
  17. from sqlalchemy import create_engine
  18.  
  19. # пример подключения к базе данных для Postresql
  20. db_config = {'user': 'my_user',
  21.             'pwd': 'my_user_password',
  22.             'host': 'localhost',
  23.             'port': 5432,
  24.             'db': 'zen'}
  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:////Users/peter/Desktop/zen.db', echo = False)
  32.  
  33. # получаем сырые данные
  34. query1 = '''
  35.            SELECT * FROM dash_visits
  36.        '''
  37. dash_visits = pd.io.sql.read_sql(query1, con = engine)
  38.  
  39.  
  40. query2 = '''
  41.            SELECT * FROM dash_engagement
  42.        '''
  43. dash_engagement = pd.io.sql.read_sql(query2, con = engine)
  44.  
  45.  
  46. # преобразуем типы в datetime в обоих датафреймах
  47. data_dict = {'dash_visits':dash_visits,'dash_engagement':dash_engagement}
  48.  
  49. for key, value in data_dict.items():
  50.   data_dict[key]['dt'] = pd.to_datetime(data_dict[key]['dt'], format = '%Y-%m-%d %H:%M:%S')
  51.  
  52.  
  53.  
  54. note = '''
  55.          Описание дашборда
  56.       '''
  57.  
  58.  
  59. # задаём лейаут
  60. external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
  61. app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
  62. app.layout = html.Div(children=[  
  63.    
  64.  
  65.     html.H1(children = 'Zen дашборд, эффективность карточек'),
  66.     html.Br(),
  67.     #------------------------ описание дашборда
  68.     html.Label(note),
  69.     #------------------------ описание дашборда
  70.    
  71.     html.Br(),
  72.  
  73.      # выбор временного периода
  74.    
  75.    
  76.     #------------------------строка_фильтры
  77.     html.Div([
  78.            
  79.     #------------------------колонка      
  80.       html.Div([
  81.         html.Label('Дата и время начала:'),
  82.             dcc.DatePickerSingle(
  83.                 id = 'start-time-date',
  84.                 display_format = 'YYYY-MM-DD',
  85.                 date = dash_visits['dt'].min()
  86.             ),
  87.             dcc.Input(id = 'start-time-hour',
  88.                       type = 'number',
  89.                       value = dash_visits['dt'].min().hour,
  90.                       step = 1,
  91.                       min = 0,
  92.                       max = 23,
  93.                       className = 'form-contro',
  94.                       ),
  95.             dcc.Input(id = 'start-time-minute',
  96.                       type = 'number',
  97.                       value = dash_visits['dt'].min().minute,
  98.                       step = 1,
  99.                       min = 0,
  100.                       max = 59,
  101.                       className = 'form-contro',
  102.                       ),
  103.  
  104.             html.Label('Дата и время окончания:'),
  105.             dcc.DatePickerSingle(
  106.                 id = 'end-time-date',
  107.                 display_format = 'YYYY-MM-DD',
  108.                 date = dash_visits['dt'].max()
  109.             ),
  110.             dcc.Input(id = 'end-time-hour',
  111.                       type = 'number',
  112.                       value = dash_visits['dt'].max().hour,
  113.                       step = 1,
  114.                       min = 0,
  115.                       max = 23,
  116.                       className = 'form-contro',
  117.                       ),
  118.             dcc.Input(id = 'end-time-minute',
  119.                       type = 'number',
  120.                       value = dash_visits['dt'].max().minute,
  121.                       step = 1,
  122.                       min = 0,
  123.                       max = 59,
  124.                       className = 'form-contro',
  125.                       ),
  126.  
  127.  
  128.         html.Label('Фильтр возрастных ограничений'),
  129.         dcc.Dropdown(
  130.               options = [{'label': x, 'value': x} for x in dash_visits['age_segment'].unique()],
  131.               value = dash_visits['age_segment'].unique(),
  132.               multi = True,
  133.               id = 'age-dropdown'),
  134.  
  135.     ], className = 'six columns'),
  136.  
  137.     #------------------------колонка
  138.  
  139.     html.Div([
  140.         html.Label('Фильтр тем карточек'),
  141.         dcc.Dropdown(
  142.               options = [{'label': x, 'value': x} for x in dash_visits['item_topic'].unique()],
  143.               value = dash_visits['item_topic'].unique(),
  144.               multi = True,
  145.               id = 'item-topic-dropdown',
  146.               style ={'height':'50%'}),
  147.  
  148.     ], className = 'six columns'),
  149.  
  150.     ], className = 'row'),
  151.     #------------------------строка_фильтры
  152.     html.Br(),
  153.  
  154.    
  155.     #------------------------строка_графики
  156.  
  157.     html.Div([
  158.  
  159.     html.Div([
  160.       html.Label('История событий по темам карточек'),
  161.       dcc.Graph(
  162.           style = {'height': '50vw'},
  163.           id = 'history-absolute-visits'
  164.         ),
  165.  
  166.       ],className='six columns'),
  167.  
  168.  
  169.     html.Div([
  170.       html.Label('Разбивка событий по темам источников'),
  171.       dcc.Graph(
  172.           style = {'height': '25vw'},
  173.           id = 'pie-visits'
  174.         ),
  175.  
  176.       ],className='six columns'),
  177.  
  178.  
  179.     html.Div([
  180.       html.Label('Средняя глубина вазимодействия'),
  181.       dcc.Graph(
  182.           style = {'height': '25vw'},
  183.           id = 'engagement-graph'
  184.         ),
  185.  
  186.       ],className='six columns'),
  187.  
  188.      
  189.  
  190.       ],className='row'),
  191.  
  192.       #------------------------строка_графики
  193.  
  194.  
  195.  
  196. ])
  197.  
  198. @app.callback(
  199.     [Output('history-absolute-visits', 'figure'),
  200.      Output('pie-visits', 'figure'),
  201.      Output('engagement-graph', 'figure'),
  202.     ],
  203.     [
  204.      Input('item-topic-dropdown', 'value'),
  205.      Input('age-dropdown', 'value'),
  206.      Input('start-time-date', 'date'),
  207.      Input('start-time-hour', 'value'),
  208.      Input('start-time-minute', 'value'),
  209.      Input('end-time-date', 'date'),
  210.      Input('end-time-hour', 'value'),
  211.      Input('end-time-minute', 'value'),    
  212.     ])
  213.  
  214.  
  215.  
  216. def update_figures(selected_item_topics, selected_ages, start_time_date, start_time_hour, start_time_minute, end_time_date, end_time_hour, end_time_minute):
  217.  
  218.  
  219.   selected_item_topics = list(selected_item_topics)
  220.   selected_ages = list(selected_ages)
  221.  
  222.   start_date = str(start_time_date) + ' {}:{}'.format(str(start_time_hour).zfill(2), str(start_time_minute).zfill(2))
  223.   end_date = str(end_time_date) + ' {}:{}'.format(str(end_time_hour).zfill(2), str(end_time_minute).zfill(2))
  224.  
  225.  
  226.  
  227.  
  228.   #-----------------------
  229.  
  230.  
  231.   #фильтр для параметров из пикеров, датафрейм dash_visits
  232.   # filtered_dash_data = dash_visits.query('item_topic.isin(@selected_item_topics) and \
  233.   #                                         dt >= @start_date and dt <= @end_date and age_segment.isin(@selected_ages)')
  234.  
  235.   filtered_dash_data = dash_visits[(dash_visits['item_topic'].isin(selected_item_topics)) and (dash_visits['age_segment'].isin(selected_ages))]
  236.   filtered_dash_data = filtered_dash_data[(filtered_dash_data['dt'] >=start_time_date) and (filtered_dash_data['dt']<= end_time_date)]
  237.  
  238.  
  239.  
  240.  
  241.   # собираем данные для графика item-topic-dropdown
  242.   filtered_dash_data_1 = filtered_dash_data.groupby(['item_topic','dt']).agg({'visits':'sum'}).reset_index()
  243.  
  244.   data_item_topic_dropdown = []
  245.  
  246.   for item in filtered_dash_data['item_topic'].unique():
  247.     current = filtered_dash_data_1[filtered_dash_data_1['item_topic']==item]
  248.     data_item_topic_dropdown += [go.Scatter(x = current['dt'],
  249.                                             y = current['visits'],
  250.                                             mode = 'lines',
  251.                                             stackgroup = 'one',
  252.                                             name = item)
  253.                                 ]
  254.  
  255.  
  256.   #собираем данные для графика pie-visits
  257.   filtered_dash_data_2 = filtered_dash_data.groupby('source_topic').agg({'visits':'sum'}).reset_index()
  258.   filtered_dash_data_2['visits'] = round((filtered_dash_data_2['visits']/filtered_dash_data['visits'].sum()),2)
  259.  
  260.   data_pie_source_topic = [go.Pie(labels = filtered_dash_data_2['source_topic'],
  261.                                   values = filtered_dash_data_2['visits'])
  262.  
  263.                           ]
  264.  
  265.   #-----------------------
  266.  
  267.   #фильтр для параметров из пикеров, датафрейм dash_engagement
  268.   # filtered_dash_data_eng = dash_engagement.query('item_topic.isin(@selected_item_topics) and \
  269.   #                                                 dt >= @start_date and dt <= @end_date \
  270.   #                                                 and age_segment.isin(@selected_ages)')
  271.  
  272.  
  273.  
  274.   filtered_dash_data_eng = dash_visits[(dash_engagement['item_topic'].isin(selected_item_topics)) and (dash_engagement['age_segment'].isin(selected_ages))]
  275.   filtered_dash_data_eng = filtered_dash_data_eng[(filtered_dash_data_eng['dt'] >=start_time_date) and (filtered_dash_data_eng['dt']<= end_time_date)]
  276.  
  277.  
  278.  
  279.   #собираем данные для графика engagement-graph
  280.   filtered_dash_data_3 = filtered_dash_data_eng.groupby('event', as_index=False).agg({'unique_users':'mean'})\
  281.                                                                             .rename(columns={'unique_users':'avg_unique_users'})\
  282.                                                                             .sort_values('avg_unique_users', ascending=False)
  283.  
  284.   data_engagement_graph = [go.Bar( x = filtered_dash_data_3['event'],
  285.                                    y = filtered_dash_data_3['avg_unique_users'],
  286.                                    name = 'Среднее количество юзеров на событие')
  287.                           ]
  288.  
  289.  
  290.  
  291.   return (
  292.                 #график item-topic-dropdown
  293.             {
  294.                 'data': data_item_topic_dropdown,
  295.                 'layout': go.Layout(xaxis = {'title': 'Время'},
  296.                                     yaxis = {'title': 'Сумма визитов'})
  297.              },
  298.  
  299.  
  300.              {  #график pie-visits
  301.                 'data': data_pie_source_topic,
  302.                 'layout': go.Layout()
  303.  
  304.              },
  305.  
  306.  
  307.              {
  308.                 #график engagement-graph
  309.                 'data': data_engagement_graph,
  310.                 'layout': go.Layout(xaxis = {'title': 'Тип События'},
  311.                                     yaxis = {'title': 'Среднее число юзеров'},
  312.                                     hovermode = 'closest')
  313.              },
  314.  
  315.  
  316.           )
  317.  
  318.  
  319.  
  320. if __name__ == '__main__':
  321.     app.run_server(debug=True)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement