当前位置: 首页 > 知识库问答 >
问题:

具有多个下拉输入的绘图仪不工作

景育
2023-03-14

我正在尝试创建一个具有多个交互式下拉用户输入变量的时间序列虚线图。理想情况下,我希望每个下拉输入都能允许多个选择。

虽然我能够成功创建下拉菜单,但图表并没有像我希望的那样更新。当我允许下拉菜单有多个选择时,我会得到一个错误,即数组的长度不同。当我将下拉列表限制为一个选项时,我得到一个错误,['Vendor_Name']不在索引中。所以这可能是两个不同的问题。

无法工作的图形:

导入DF的Excel数据片段

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
#import plotly.graph_objs as go 
df = pd.read_csv("Data.csv", sep = "\t")
df['YearMonth'] = pd.to_datetime(df['YearMonth'], format = '%Y-%m')
cols = ['Product_1', 'Product_2', 'Product_3']
vendor = df['Vendor'].unique()

app = dash.Dash('Data')

app.layout = html.Div([
    html.Div([
        html.Div([

            html.Label('Product'),
            dcc.Dropdown(
                 id = 'product',
                 options = [{
                         'label' : i, 
                         'value' : i
                 } for i in cols],
                multi = True,
                value = 'Product_1'

                 ),
                ]),

        html.Div([

            html.Label('Vendor'),
            dcc.Dropdown(
             id = 'vendor',
             options = [{
                     'label' : i, 
                     'value' : i
             } for i in vendor],
            multi = True,
             value = 'ABC')
             ,
        ]),
            ]),

    dcc.Graph(id = 'feature-graphic')
    ])


@app.callback(Output('feature-graphic', 'figure'),
    [Input('product', 'value'),
     Input('vendor', 'value')])


def update_graph(input_vendor, input_column):


    df_filtered = df[df['Vendor'] == input_vendor]

##also tried setting an index because of the error I was getting. Not sure if necessary
    df_filtered = df_filtered.set_index(['Vendor']) 

    traces = []

    df_by_col = df_filtered[[input_column, 'YearMonth']]

    traces.append({

        'x' :pd.Series(df_by_col['YearMonth']),
        'y' : df_by_col[input_column],
        'mode' : 'lines',
        'type' : 'scatter',
        'name' :'XYZ'}
        )

    fig = {
                    'data': traces,
                    'layout': {'title': 'Title of Chart'}
                    }
    return fig


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

提前感谢您的帮助!对Python来说还是新手,但对Dash的功能非常兴奋。我已经能够用单个输入创建其他图形,并且已经通读了文档。

共有2个答案

关翰
2023-03-14

csv中的数据很难循环。我认为这是你的代码不起作用的主要原因,因为你似乎理解基本的代码结构。戴上我的SQL眼镜后,我想你应该试着让它变得更好

Date, Vendor, ProductName, Value

multi是个棘手的问题,因为如果只选择了一个项目,它会在返回str列表之间切换

代码返回一个dict,但回调声明figure为返回类型

但是下面是带有调试痕迹的代码,这些痕迹是print()sleep()

import pandas as pd
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
import time

df = pd.read_csv("Data.csv", sep="\t")
df['YearMonth'] = pd.to_datetime(df['YearMonth'], format='%Y-%m')
products = ['Product_1', 'Product_2', 'Product_3']
vendors = df['Vendor'].unique()

app = dash.Dash('Data')

app.layout = html.Div([
    html.Div([
        html.Div([
            html.Label('Product'),
            dcc.Dropdown(
                id='product',
                options=[{'label' : p, 'value' : p} for p in products],
                multi=True,
                value='Product_1'
            ),
        ]),
        html.Div([
            html.Label('Vendor'),
            dcc.Dropdown(
                id='vendor',
                options=[{'label': v, 'value': v} for v in vendors],
                multi=True,
                value='ABC'
            ),
        ]),
    ]),
    dcc.Graph(id='feature-graphic', figure=go.Figure())
])


@app.callback(
    Output('feature-graphic', 'figure'),
    [Input('product', 'value'),
     Input('vendor', 'value')])
def update_graph(input_product, input_vendor):
    # df_filtered[['Product_1', 'YearMonth']]
    if type(input_product) == str:
        input_product = [input_product]
    if type(input_vendor) == str:
        input_vendor= [input_vendor]

    datasets = ['']
    i = 1
    for vendor in input_vendor:
        df_filtered = df[df['Vendor'] == vendor]
        for product in input_product:
            datasets.append((df_filtered[['YearMonth', 'Vendor', product]]).copy())
            datasets[i]['ProductName'] = product
            datasets[i].rename(columns={product: 'Value'}, inplace=True)
            i += 1
    datasets.pop(0)
    print(datasets)

    traces = ['']
    for dataset in datasets:
        print(dataset)
        time.sleep(1)
        traces.append(
            go.Scatter({
                'x': dataset['YearMonth'],
                'y': dataset['Value'],
                'mode': 'lines',
                'name': f"Vendor: {dataset['Vendor'].iloc[0]} Product: {dataset['ProductName'].iloc[0]}"
        }))
    traces.pop(0)
    layout = {'title': 'Title of Chart'}

    fig = {'data': traces, 'layout': go.Layout(layout)}
    return go.Figure(fig)


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

如果你处理1。它将大大简化一切。因此,我将尝试将pd.DataFrame()从回调中分离出来,并放入上层I/O部分。

1)不要在循环中使用计数器

2) 我的变量名也不是最好的

3) 下面的样式是caveman的python,肯定有更好的方法:

traces = ['']
traces.append(this_and_that)
traces.pop(0)

使用print(input_variable)print(type(input_variable))可以让我的车轮大部分时间摆脱泥泞。

您应该注意到,每个跟踪都有各自的名称,该名称将显示在图例中。单击图例中的名称将添加或删除跟踪,而无需@app.callback()

陶鹏
2023-03-14

以下是我遵循的方法:(使用我的方法编辑google中可用的常见示例):

import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash(__name__)

all_options = {
    'America': ['New York City', 'San Francisco', 'Cincinnati'],
    'Canada': [u'Montréal', 'Toronto', 'Ottawa']
}
app.layout = html.Div([
    dcc.Dropdown(
        id='countries-dropdown',
        options=[{'label': k, 'value': k} for k in all_options.keys()],
        value='America',  #default value to show
        multi=True,
        searchable=False
    ),

    dcc.Dropdown(id='cities-dropdown', multi=True, searchable=False, placeholder="Select a city"),

    html.Div(id='display-selected-values')
])

@app.callback(
    dash.dependencies.Output('cities-dropdown', 'options'),
    [dash.dependencies.Input('countries-dropdown', 'value')])
def set_cities_options(selected_country):
    if type(selected_country) == 'str':
        return [{'label': i, 'value': i} for i in all_options[selected_country]]
    else:
        return [{'label': i, 'value': i} for country in selected_country for i in all_options[country]]

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

这里的解决方法是:当父下拉列表中存在单个输入时,值为字符串格式。但对于多个值,它是列表格式的。
此代码也可以完美地工作,即使您单击“交叉选项”删除任何选定的选项,也会自动更新。

注意:我使用了占位符属性,而不是为它定义默认值,因为在这种情况下它没有意义。但是您也可以以类似的方式动态更新值。

 类似资料:
  • 问题内容: 我正在尝试做的是拥有多个具有不同变量的输入。每个变量将是不同方程式的一部分。我正在寻找一种方法来做,我想我有一个主意。我只想知道这是否合法,也许还有更好的方法。 问题答案: 如果每个输入都问相同的问题,则应使用循环和输入数组: 或者如Chip所建议的,您可以从一行中解析输入: 您在正确的轨道上,所做的工作正常。这只是一种更好,更灵活的处理方式。

  • 我的谷歌表单使用了用户马克斯·马克洛夫(Max Makhrov)编写的代码,这里的代码,在D-F列(用于位置)和H-L列(用于目标)中创建多个相关的动态下拉列表 我想帮助修改脚本以完成两件事: 无论从第一列的下拉菜单中选择了什么活动,我都希望J-L列可以使用相同的下拉菜单选项(重复)。正如您所看到的,我找到了一种方法,但对我来说,它似乎笨重且不理想,并且为错误留下了太多的空间。用户不应该选择活动两

  • 因此,我是一个新的Java程序员,我正试图弄清楚为什么一段代码不能工作。我遇到的问题是“String interests=input.nextLine();”这一行,它跳过了用户的输入并跳转到下一个System.out,所以它只显示“Your Profile...”。在允许用户输入任何数据之前。抱歉,如果这是一个愚蠢的问题,我是很新的!

  • 绘图工具栏 绘图工具栏位于主窗口左侧。绘图工具包括选择、框选(和框选墙)、画墙(和画矩形墙)、给墙加点和擦除功能。 名称 说明 选择 选择场景中任意对象(如模型、墙体),并对其进行编辑(快捷键为1)。 框选(和框选墙) 可框选多个模型。长按可选择框选墙,用于选择多个墙体。 画墙(和画矩形墙) 绘制墙体。长按可选择画矩形墙。 给墙加点 给整面的墙体添加锚点,给墙体分段。 擦除 删除墙体。

  • 本文向大家介绍js实现Select下拉框具有输入功能的方法,包括了js实现Select下拉框具有输入功能的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了js实现Select下拉框具有输入功能的方法。分享给大家供大家参考。具体实现方法如下: 实现方法一 实现方式二 希望本文所述对大家的javascript程序设计有所帮助。

  • 我在nodejs中有一个查询,如下所示。但它不返回任何值。有什么办法解决这个问题吗?