Я пытаюсь создать свою первую панель с Dash на основе набора данных по раку молочной железы Kaggle, найденного здесь .
В настоящее время я работаю над добавлением тепловой карты корреляции, где я хочуиметь возможность выбирать между диагнозом (т. е. злокачественным и доброкачественным) в раскрывающемся меню, а также между методами корреляции (т. е. Пирсона, Кендалла, Спирмена).
К сожалению, при попытке создать тепловую карту япродолжайте получать следующее сообщение об ошибке:
Traceback (most recent call last):
File "~/sandbox/apps/heatmap.py", line 52, in update_heatmap
heatmap_data = df[(df['diagnosis'] ==
diagnosis_dropdown)].drop(['diagnosis', 'target'], axis=1)
File "~/venv/lib/python3.7/site-packages/pandas/core/ops/__init__.py", line 1207, in wrapper
raise ValueError("Lengths must match to compare")
ValueError: Lengths must match to compare
Матрица тепловой карты имеет размер 5x5, поэтому я не понимаю, почему длины не совпадают - или как двигаться вперед.
Сделайте кого-нибудь из васзнаете, как решить эту проблему, когда в раскрывающемся меню можно выбрать диагноз и просмотреть матрицу корреляции для этого диагноза?
Дерево моего приложения:
.
|-- app.py
|-- apps
| |-- data_prep.py
| |-- heatmap.py
| |-- home.py
| `-- sidebar.py
|-- data
| `-- breast_cancer.csv
`-- index.py
Сценарии- Я думаю, что проблема в "heatmap.py".
app.py
# -*- coding: utf-8 -*-
import dash
import dash_core_components as dcc
import dash_bootstrap_components as dbc
# dash bootstrap components:
app = dash.Dash(__name__, external_stylesheets= [dbc.themes.BOOTSTRAP])
server = app.server
app.config.suppress_callback_exceptions = True
index.py
# -*- coding: utf-8 -*-
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
from app import app
from apps import heatmap
from apps.sidebar import *
from apps.data_prep import *
# Sidebar layout
app.layout = html.Div([dcc.Location(id="url", pathname='/'), sidebar, content])
@app.callback(Output("page-content", "children"), [Input("url", "pathname")])
def render_page_content(pathname):
if pathname in ["/", "/home"]:
return home.layout
elif pathname == "/heatmap":
return heatmap.layout
else:
return dbc.Jumbotron(
[
html.H1("404: Not found", className="text-danger"),
html.Hr(),
html.P(f"The pathname {pathname} was not recognised..."),
]
)
if __name__ == '__main__':
app.run_server(debug=True)
apps / home.py
# -*- coding: utf-8 -*-
import dash_html_components as html
layout = html.Div([
html.Br(),
html.H3('Welcome'),
])
apps / data_prep.py
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
# load the data
df = pd.read_csv("./data/breast_cancer.csv")
# rename diagnosis
df['diagnosis'] = df['diagnosis'].replace({0: 'benign', 1: 'malignant'})
# create new column with target: benign: 0; malignant: 1
df['target'] = df['diagnosis'].apply(lambda x: 1 if x == 'malignant' else 0)
# extract metric names (old column names)
diagnosis_names = df['diagnosis'].unique()
apps / sidebar.py
import dash_bootstrap_components as dbc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from app import app
# the style arguments for the sidebar. We use position:fixed and a fixed width
SIDEBAR_STYLE = {
"position": "fixed",
"top": 0,
"left": 0,
"bottom": 0,
"width": "16rem",
"padding": "2rem 1rem",
"background-color": "#f8f9fa",
}
# the styles for the main content position it to the right of the sidebar and
# add some padding.
CONTENT_STYLE = {
"margin-left": "18rem",
"margin-right": "2rem",
"padding": "2rem 1rem",
}
submenu_1 = [
html.Li(
# use Row and Col components to position the chevrons
dbc.Row(
[
dbc.Col("Menu 1"),
dbc.Col(width="auto"),
],
className="my-1",
),
id="submenu-1",
),
# we use the Collapse component to hide and reveal the navigation links
dbc.Collapse(
[
dbc.NavLink("Home", href="/"),
dbc.NavLink("Heatmap", href="/heatmap"),
],
id="submenu-1-collapse",
),
]
sidebar = html.Div(
[
html.H2("Content", className="display-7"),
html.Hr(),
dbc.Nav(submenu_1, vertical=True),
],
style=SIDEBAR_STYLE,
id="sidebar",
)
content = html.Div(id="page-content", style=CONTENT_STYLE)
# this function is used to toggle the is_open property of each Collapse
def toggle_collapse(n, is_open):
if n:
return not is_open
return is_open
# this function applies the "open" class to rotate the chevron
def set_navitem_class(is_open):
if is_open:
return "open"
return ""
for i in [1, 2]:
app.callback(
Output(f"submenu-{i}-collapse", "is_open"),
[Input(f"submenu-{i}", "n_clicks")],
[State(f"submenu-{i}-collapse", "is_open")],
)(toggle_collapse)
app.callback(
Output(f"submenu-{i}", "className"),
[Input(f"submenu-{i}-collapse", "is_open")],
)(set_navitem_class)
apps / heatmap.py
# -*- coding: utf-8 -*-
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 apps.data_prep import *
from app import app
layout = html.Div([
html.Br(),
html.H3("Correlation heatmap"),
dcc.Tabs(
id='corr-tabs',
value='corr-heatmap',
children=[dcc.Tab(label='Correlation Heatmap', value='corr-heatmap')]),
html.Div(id='tabs-content')
])
@app.callback(Output('tabs-content', 'children'),
[Input('corr-tabs', 'value')])
def render_content(tab):
if tab == 'corr-heatmap':
return html.Div([
html.H3('Correlation Heatmap'),
html.Div([
html.Div([
html.Div([
html.H1('Select diagnosis'),
dcc.Dropdown(
id='diagnosis_dropdown',
options=[{'label': 'Benign', 'value': 'benign'},
{'label': 'Malignant', 'value': 'malignant'}],
value='benign'
)],
style={'width': '20%', 'display': 'inline-block'}),
dcc.Graph(id='corr-heatmap')])])])
@app.callback(Output('corr-heatmap', 'figure'),
[Input('diagnosis_dropdown', 'options')])
def update_heatmap(diagnosis_dropdown):
heatmap_data = df[(df['diagnosis'] == diagnosis_dropdown)].drop(['diagnosis', 'target'], axis=1)
return {
'data': [go.Heatmap(
x=heatmap_data.columns,
y=heatmap_data.columns,
z=heatmap_data.corr(method='pearson').as_matrix(),
colorbar=dict(title="Pearson Coefficient"))]}