Advertisement
Guest User

Untitled

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