Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- # -*- coding: utf-8 -*-
- import dash
- import dash_core_components as dcc
- import dash_html_components as html
- from dash.dependencies import Input, Output
- import plotly.graph_objs as go
- from datetime import datetime
- import pandas as pd
- import numpy as np
- # задаём данные для отрисовки
- from sqlalchemy import create_engine
- # пример подключения к базе данных для Postresql
- db_config = {'user': 'my_user',
- 'pwd': 'my_user_password',
- 'host': 'localhost',
- 'port': 5432,
- 'db': 'zen'}
- engine = create_engine('postgresql://{}:{}@{}:{}/{}'.format(db_config['user'],
- db_config['pwd'],
- db_config['host'],
- db_config['port'],
- db_config['db']))
- # пример подключения к базе данных для Sqlite
- # engine = create_engine('sqlite:////db/zen.db', echo=False)
- # получаем сырые данные
- query = '''
- SELECT * FROM dash_visits
- '''
- dash_visits = pd.io.sql.read_sql(query, con = engine)
- dash_visits['dt'] = pd.to_datetime(dash_visits['dt'])
- query = '''
- SELECT * FROM dash_engagement
- '''
- dash_engagement = pd.io.sql.read_sql(query, con = engine)
- dash_engagement['dt'] = pd.to_datetime(dash_engagement['dt'])
- note = '''
- Этот дашборд отвечает на следующие вопросы: Насколько активно пользователи взаимодействуют с карточками? В каких темах сколько карточек?
- Какова конверсия из "увидевшего" в "прочитавшего"?
- '''
- # задаём лейаут
- external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
- app = dash.Dash(__name__, external_stylesheets=external_stylesheets, compress=False)
- app.layout = html.Div(children=[
- # формируем html
- html.H1(children = 'Яндекс.Дзен. Пользователи и карточки'),
- html.Br(),
- # пояснения
- html.Label(note),
- html.Br(),
- html.Div([
- html.Div([
- html.Div([
- # выбор времени
- html.Label('Время'),
- dcc.DatePickerRange(
- start_date = dash_visits['dt'].min(),
- end_date = dash_visits['dt'].max(),
- display_format = 'YYYY-MM-DD HH:MM',
- id = 'dt_selector'),
- ], className = 'row container-display'),
- html.Div([
- #выбор возрастной группы
- html.Label('Возрастная группа'),
- dcc.Dropdown(
- options = [{'label': x, 'value': x} for x in dash_visits['age_segment'].unique()],
- value = dash_visits['age_segment'].unique().tolist(),
- multi = True,
- id = 'age_selector'
- ),
- ], className = 'row container-display'
- ),
- ], className = 'six columns'
- ),
- html.Div([
- #выбор темы карточки
- html.Label('Тема карточки'),
- dcc.Dropdown(
- options = [{'label': x, 'value': x} for x in dash_visits['item_topic'].unique()],
- value = dash_visits['item_topic'].unique().tolist(),
- multi = True,
- id = 'topic_selector'
- ),
- ], className = 'six columns'
- ),
- ]),
- html.Br(),
- html.Div([
- html.Div([
- # график история событий по темам карточек (все типы событий, абсолютные значения)
- html.Label('История событий по темам карточек'),
- dcc.Graph(
- style = {'height': '50vw'},
- id = 'history_type_of_cards'
- ),
- ], className = 'six columns'),
- html.Div([
- # график события по темам источников
- html.Label('События по темам источников'),
- dcc.Graph(
- style = {'height': '25vw'},
- id = 'events_by_source'
- ),
- ], className = 'six columns'),
- html.Div([
- # график глубины взаимодействия
- html.Label('Глубина взаимодействия'),
- dcc.Graph(
- style = {'height': '25vw'},
- id = 'depth_of_engagement'
- ),
- ], className='six columns'),
- ])
- ])
- #описываем логику дашборда
- @app.callback(
- [Output('history_type_of_cards', 'figure'),
- Output('events_by_source', 'figure'),
- Output('depth_of_engagement', 'figure'),
- ],
- [Input('dt_selector', 'start_date'),
- Input('dt_selector', 'end_date'),
- Input('topic_selector', 'value'),
- Input('age_selector', 'value'),
- ])
- def update_figures(start_date, end_date, topic_selector, age_selector):
- #применяем фильтрацию
- filtered = dash_visits.query('item_topic.isin(@topic_selector) and \
- dt >= @start_date and dt <= @end_date \
- and age_segment.isin(@age_selector)')
- history_dash_visits = (filtered.groupby(['dt', 'item_topic'], as_index=False)
- .agg({'visits': 'sum'})
- .reset_index()
- )
- events_dash_visits = (filtered.groupby(['source_topic'], as_index=False)
- .agg({'visits': 'sum'})
- .reset_index()
- )
- filtered = dash_engagement.query('item_topic.isin(@topic_selector) and \
- dt >= @start_date and dt <= @end_date \
- and age_segment.isin(@age_selector)')
- bottleneck_dash_engagement = (filtered.groupby(['event'])
- .agg({'unique_users':'mean'})
- .reset_index())
- bottleneck_dash_engagement.rename(columns={'unique_users':'avg_unique_users'}, inplace=True)
- bottleneck_dash_engagement = bottleneck_dash_engagement.sort_values(by='avg_unique_users', ascending=False)
- # график история событий по темам карточек (все типы событий, абсолютные значения)
- history = []
- for topic in history_dash_visits['item_topic'].unique():
- history += [go.Scatter(x = history_dash_visits.query('item_topic == @topic_selector')['dt'],
- y = history_dash_visits.query('item_topic == @topic_selector')['visits'],
- mode = 'lines',
- stackgroup = 'one',
- #cumulative_enabled=True,
- name = topic)]
- # график события по темам источников
- piechart_dash_engagement = [go.Pie(labels = events_dash_visits['source_topic'],
- values = events_dash_visits['visits'])]
- # график глубины взаимодействия
- bottleneck_chart = [go.Bar(x = bottleneck_dash_engagement['event'],
- y = bottleneck_dash_engagement['avg_unique_users'])]
- #формируем результат для отображения
- return (
- {
- 'data': history,
- 'layout': go.Layout(xaxis = {'title': 'Время'},
- yaxis = {'title': 'Посещения'})
- },
- {
- 'data': piechart_dash_engagement,
- 'layout': go.Layout()
- },
- {
- 'data': bottleneck_chart,
- 'layout': go.Layout(xaxis = {'title': 'Событие'},
- yaxis = {'title': 'Ср.кол. уник.пользователей'})
- }
- )
- if __name__ == '__main__':
- app.run_server(debug=True)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement