Advertisement
mironovichandrei

Untitled

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