Advertisement
Guest User

Untitled

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