Создайте график в да sh -плоте на основе выпадающего списка и даты выбора для определенного уникального значения - PullRequest
4 голосов
/ 12 января 2020

У меня есть простая база данных, как на картинке ниже:

enter image description here

, и запрос выглядит так:

SELECT 
       [Date]
      ,[eNodeBName]
      ,[Downlinkbandwidth]
      ,[DownlinkEARFCN]
      ,[CellName]
      ,[LocalCellId]
      ,[PhysicalcellID]
      ,[LRRCConnReqAtt]
      ,[RRCSetupSuccessRate]
      ,[InterFreqSuccessRate4G]
      ,[IntraRATHOSucccessRate]
      ,[IntraFreqSuccessRate4G]
      ,[CellDLMaxThroughputMbps]
      ,[CellDownlinkAverageThroughputMbps]
  FROM [myDB].[dbo].[input]

Теперь мне нужно создать интерактивную диаграмму, которая зависит от входных данных, таких как указатель даты и выпадающий список.

Поскольку это образец GUI, который я создал для диаграммы, выведите эти входные данные, как показано на рисунке ниже:

enter image description here

Теперь я создаю диаграмму на основе названия столбцов, как показано на рисунке ниже:

enter image description here

, так как это связанный запрос, как показано ниже:

SELECT 
       [Date]
      ,[CellName]
      ,[LRRCConnReqAtt]
      ,[RRCSetupSuccessRate]
      ,[InterFreqSuccessRate4G]
      ,[IntraRATHOSucccessRate]
      ,[IntraFreqSuccessRate4G]
      ,[CellDLMaxThroughputMbps]
      ,[CellDownlinkAverageThroughputMbps]
  FROM [myDB].[dbo].[input]

Так что теперь ось X должна быть столбцом Date, а ось y связана с приведенными ниже. столбцы KPI столбцы:

SELECT 
       [LRRCConnReqAtt]
      ,[RRCSetupSuccessRate]
      ,[InterFreqSuccessRate4G]
      ,[IntraRATHOSucccessRate]
      ,[IntraFreqSuccessRate4G]
      ,[CellDLMaxThroughputMbps]
      ,[CellDownlinkAverageThroughputMbps]
  FROM [myDB].[dbo].[input]

Итак, теперь у нас есть уникальный столбец, содержащий уникальные значения, называется CellName, это имя ячейки, я хочу создать простую диаграмму для этого уникального значения на основе даты columnn и столбец KPI.

Так, например, я хочу показать график для определенного CellName = 2002334 для KPI * 1 039 * по данным с 27 декабря по 9 января. Поэтому мне нужна диаграмма, как показано на рисунке ниже, и это пример диаграммы, созданной в Excel.

enter image description here

и это мой код:

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
from sqlalchemy import create_engine
import datetime
from datetime import datetime as dt
from dash.dependencies import Input, Output

# connect db
engine = create_engine('mssql+pyodbc://xxxxxx\SMxxxxxARTRNO_EXPRESS/myDB?driver=SQL+Server+Native+Client+11.0')
cursor = engine.raw_connection().cursor()

start = datetime.datetime(2019, 12, 2)
end = datetime.datetime(2019, 12, 15)

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

lte_kpis = pd.read_sql('SELECT * FROM [myDB].[dbo].[input]',
                       engine)

lte_kpis_raw = pd.read_sql('SELECT LRRCConnReqAtt, RRCSetupSuccessRate, InterFreqSuccessRate4G, IntraRATHOSucccessRate, IntraFreqSuccessRate4G,CellDLMaxThroughputMbps, CellDownlinkAverageThroughputMbps FROM [myDB].[dbo].[input]',
                           engine)

scale_1 = ['LRRCConnReqAtt']
scale_2 = ['RRCSetupSuccessRate', 'InterFreqSuccessRate4G', 'IntraRATHOSucccessRate', 'IntraFreqSuccessRate4G']
scale_3 = ['CellDLMaxThroughputMbps', 'CellDownlinkAverageThroughputMbps']

pd.set_option('display.max_columns', 500)
pd.set_option('display.width', 1000)

availble_cell = lte_kpis['CellName'].unique()

# availble_cell = lte_kpis.unique(lte_kpis[['Date', 'Site Name', 'Cell CI', 'Cell LAC']].values.ravel('K'))

app.layout = html.Div([
    dcc.Dropdown(
        id='cell-name-xaxis-column',
        options=[{'label': i, 'value': i} for i in availble_cell],
        value='2205516'
    ),

    dcc.Dropdown(
        id='myColumns',
        options=[{'label': col, 'value': col} for col in lte_kpis_raw.columns],
        multi=True,
        value='LRRCConnReqAtt'
    ),

    dcc.DatePickerRange(
        id='my-date-picker-range',
        min_date_allowed=dt(1995, 8, 5),
        max_date_allowed=dt(2030, 9, 19),
        initial_visible_month=dt(2019, 10, 5),
        start_date=dt(2019, 10, 1),
        end_date=dt(2020, 1, 1)
    ),
    html.Div(id='output-container-date-picker-range'),

    dcc.Graph(
        style={'height': 300},
        id='my-graph'
    )

])


@app.callback(
    Output('my-graph', 'figure'),
    [Input('cell-name-xaxis-column', 'value'),
     Input('myColumns', 'value')])
def update_graph(xaxis_column_name, yaxis_column_name, date_value):
    dff = lte_kpis[lte_kpis['Date'] == date_value]

    return {
        'data': [dict(
            x=dff[dff['Date'] == xaxis_column_name]['Value'],
            y=dff[dff['Date'] == yaxis_column_name]['Value'],
            text=dff[dff['Date'] == yaxis_column_name]['CellName'],
            mode='line',
            line={
                'size': 15,
                'opacity': 0.5
            }
        )],
    }


if __name__ == '__main__':
    app.run_server(debug=True)

Обратите внимание, что я хочу разместить более одного KPI на одном графике с разными графиками ....

Поскольку значения шкалы в этих KPI немного отличаются, поэтому я попытался создать три типа объектов со значениями масштаба имен столбцов, как показано ниже:

scale_1 = ['LRRCConnReqAtt']
scale_2 = ['RRCSetupSuccessRate', 'InterFreqSuccessRate4G', 'IntraRATHOSucccessRate', 'IntraFreqSuccessRate4G']
scale_3 = ['CellDLMaxThroughputMbps', 'CellDownlinkAverageThroughputMbps']

, и это ошибка, которую я обнаружил:

TypeError: update_graph() missing 1 required positional argument: 'date_value'

Traceback (most recent call last)
File "C:\Users\mwx825326\PycharmProjects\MyReference\venv\Lib\site-packages\dash\dash.py", line 1337, in add_context
output_value = func(*args, **kwargs)  # %% callback invoked %%
TypeError: update_graph() missing 1 required positional argument: 'date_value'
Traceback (most recent call last):
  File "C:\Users\mwx825326\PycharmProjects\MyReference\venv\Lib\site-packages\dash\dash.py", line 1337, in add_context
    output_value = func(*args, **kwargs)  # %% callback invoked %%
TypeError: update_graph() missing 1 required positional argument: 'date_value'

Любая помощь приветствуется. !!!!

1 Ответ

0 голосов
/ 15 января 2020

Теперь этот вопрос решен ..

Но мне это нужно более подробно c, и мне нужно удалить один Drop-down и создать диаграмму на основе одного Drop-down и Date-Picker вместо 2 Drop-down, поскольку съемный выпадающий список основан на столбцах в DB in y-axis ...

Сначала я создал массивы для каждого столбца, который должен быть столбцом оси Y, так как я хочу сделать это stati c диаграмм для каждого мульти или одного столбца в одной диаграмме на основе значения другого столбца или нескольких столбцов в базе данных ....

как приведенный ниже код:

SHOW_COLUMNS1 = [
    'lrrc_re_est_succ',
    'cell_dl_max_throughput'
]

SHOW_COLUMNS2 = [
    'interfreq_success_rate_4g',
    'intrarat_ho_success_rate'
]

SHOW_COLUMNS3 = [
    'rcc_setup_success_rate',
    'interfreq_success_rate_4g'
]

SHOW_COLUMNS4 = [
    'cell_downlink_average_throughput'
]

после этого соединение с Date-Base

# connect db
engine = create_engine('mssql+pyodbc://xxxxxx\zzzzzz/myDB?driver=SQL+Server+Native+Client+11.0')
cursor = engine.raw_connection().cursor()
lte_kpis = pd.read_sql('SELECT * FROM [myDB].[dbo].[lte_details]', engine)

после этого я создал GUI для интерактивных диаграмм и pandas, читаемый как следующий код:

lte_kpis = pd.read_sql('SELECT * FROM [myDB].[dbo].[lte_details]', engine)
pd.set_option('display.max_columns', 10000)
print(lte_kpis)

lte_kpis.set_index('date', inplace=True)

availble_cell = lte_kpis['cell_name'].unique()

plots = []
app.layout = html.Div([
    html.H5(
        'Huawei KPI Dashbord'),

    html.Label('Choose the "Cell-Name"'),
    dcc.Dropdown(
        id='cell-name-xaxis-column',
        options=[{'label': i, 'value': i} for i in availble_cell],
        value= availble_cell[0]
    ),
    html.Label('Choose Date Destination'),
    dcc.DatePickerRange(
        id='date-picker-range',
        min_date_allowed=dt(1995, 8, 5),
        max_date_allowed=dt(2030, 9, 19),
        initial_visible_month=dt(2019, 10, 5),
        start_date=dt(2019, 10, 1),
        end_date=dt(2020, 1, 1)
    ),
    html.Div(id='output-container-date-picker-range-%s'),
    dcc.Dropdown(
        id='yaxis-columns',
        options=[{'label': col, 'value': col} for col in SHOW_COLUMNS1],
        multi=True,
        disabled=True,
        value=[SHOW_COLUMNS1[0], SHOW_COLUMNS1[1]]
    ),
    dcc.Graph(
        style={'height': 300},
        id='my-graph'
    ),
    dcc.Dropdown(
        id='yaxis-columns2',
        options=[{'label': col, 'value': col} for col in SHOW_COLUMNS2],
        multi=True,
        disabled=True,
        value=[SHOW_COLUMNS2[0], SHOW_COLUMNS2[1]]
    ),
    dcc.Graph(
        style={'height': 300},
        id='my-graph2'
    ),
    dcc.Dropdown(
        id='yaxis-columns3',
        options=[{'label': col, 'value': col} for col in SHOW_COLUMNS3],
        multi=True,
        disabled=True,
        value=[SHOW_COLUMNS3[0], SHOW_COLUMNS3[1]]
    ),
    dcc.Graph(
        style={'height': 300},
        id='my-graph3'
    ),
    dcc.Dropdown(
        id='yaxis-columns4',
        options=[{'label': col, 'value': col} for col in SHOW_COLUMNS4],
        multi=True,
        disabled=True,
        value=[SHOW_COLUMNS4[0]]
    ),
    dcc.Graph(
        style={'height': 300},
        id='my-graph4'
    ),

])

и это Call-back

@app.callback(
    Output(component_id='my-graph2', component_property='figure'),
    [Input(component_id='cell-name-xaxis-column', component_property='value'),
     Input(component_id='yaxis-columns2', component_property='value'),
     Input(component_id='date-picker-range', component_property='start_date'),
     Input(component_id='date-picker-range', component_property='end_date')])
def update_graph(cell_name, yaxis_cols, start_date, end_date):
    if not isinstance(yaxis_cols, list):
        yaxis_cols = [yaxis_cols]
    print(yaxis_cols)
    print((start_date, end_date))

    sql_statement = "SELECT date, %s, %s FROM [myDB].[dbo].[lte_details] WHERE ([cell_name]='%s' AND [date]>='%s' AND [date]<='%s')" \
                    % (SHOW_COLUMNS2[0], SHOW_COLUMNS2[1], cell_name, start_date, end_date)
    df = pd.read_sql(sql_statement, engine)

    scatters = []

    for col in yaxis_cols:
        if col == 'lrrc_conn_req_att':
            scatters.append(go.Bar(
                x=df['date'],
                y=df[col],
                mode='lines',
                name=col
            ))
        else:
            scatters.append(go.Scatter(
                x=df['date'],
                y=df[col],
                name=col
            ))

    figure = {
        'data': scatters,
    }

    return figure

Обратите внимание, что, поскольку предыдущая ошибка связана с отсутствием типа данных в базе данных при импорте файла Excel в базу данных, связанную с приведенным ниже кодом:

col_dict = {
    'date': 'Date',
    'enodeb_name': 'eNodeB Name',
    'downlink_bandwidth': 'Downlink bandwidth',
          ...........................
}
LTE_DETAILS_TABLE = 'lte_details'

cols = list(col_dict.keys())

# connect db
engine = create_engine('mssql+pyodbc://xxxxx\xxxxxx/myDB?driver=SQL+Server+Native+Client+11.0')
connection = engine.connect()

meta = MetaData()
ltedetails = Table(
    LTE_DETAILS_TABLE, meta,
    Column('id', Integer, primary_key=True),
    Column(cols[0], Date),
    Column(cols[1], String),
    Column(cols[2], String),
       .................................
)

if engine.dialect.has_table(engine, LTE_DETAILS_TABLE):
    ltedetails.drop(engine)
meta.create_all(engine)

lte_df = pd.read_excel(os.path.join(os.path.dirname(__file__), 'input.xlsx'), sheet_name='LTE Details', dtype={
    col_dict[cols[0]]: str,
    col_dict[cols[1]]: str,
    col_dict[cols[2]]: str,
        .....................................
})
lte_df['Date'] = pd.to_datetime(lte_df['Date'], errors='coerce')

query = db.insert(ltedetails)
values_list = []
row_count = 1
for i in lte_df.index:
    row = lte_df.loc[i]
    record = {'id': row_count}
    for col in col_dict.keys():
        if col == cols[3] or col == cols[4] or col == cols[5] or col == cols[6] or col == cols[7] or col == cols[8]:
            record[col] = int(row[col_dict[col]])
        elif col == cols[9] or col == cols[10] or col == cols[11] or col == cols[12] or col == cols[13] or col == cols[14]:
            record[col] = float(row[col_dict[col]])
        else:
            record[col] = row[col_dict[col]]
    values_list.append(record)
    row_count += 1

ResultProxy = engine.execute(query, values_list)

connection.close()
engine.dispose()

Так что я застрял сейчас, я хочу удалить Dropp-down с идентификатором ``, ​​который lled id='yaxis-columns', ...

Так что если есть какие-либо комментарии о том, как улучшить производительность этого кода, и о завершении, чтобы решить мою проблему ..

Я рад за это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...