Как решить "ValueError: Длина должна совпадать, чтобы сравнить", используя go.Heatmap? - PullRequest
0 голосов
/ 18 октября 2019

Я пытаюсь создать свою первую панель с 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"))]}
...