Advertisement
Guest User

Untitled

a guest
Feb 19th, 2020
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.84 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