我有一个简单的破折号应用程序,用户可以在其中上传数据集,并且该应用程序输出第一列与第二列的简单散点图(因此只有第一列/第二列中具有连续值的数据才有效)
我希望用户能够上传多个数据集并显示每个数据集的图表。
例如,如果用户要上传三个不同的数据集,则 dash 应用程序将显示要上传的第一个数据集的图表,然后是要上传的第二个数据集的图表,然后是第三个数据集的图表待上传。
我该怎么做?这是我当前的代码:
import base64
import datetime
import io
import plotly.graph_objs as go
import plotly.express as px
import dash
from dash.dependencies import Input, Output, State
from dash import dcc, html, dash_table, Patch
import numpy as np
import pandas as pd
external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
server = app.server
colors = {"graphBackground": "#F5F5F5", "background": "#ffffff", "text": "#000000"}
app.layout = html.Div(
[
dcc.Upload(
id="upload-data",
children=html.Div(["Drag and Drop or ", html.A("Select Files")]),
multiple=True,
),
html.Div(id="graph1"),
]
)
def parse_data(contents, filename):
content_type, content_string = contents.split(",")
decoded = base64.b64decode(content_string)
try:
if "csv" in filename:
# Assume that the user uploaded a CSV or TXT file
df = pd.read_csv(io.StringIO(decoded.decode("utf-8")))
elif "xls" in filename:
# Assume that the user uploaded an excel file
df = pd.read_excel(io.BytesIO(decoded))
elif "txt" or "tsv" in filename:
# Assume that the user upl, delimiter = r'\s+'oaded an excel file
df = pd.read_csv(io.StringIO(decoded.decode("utf-8")), delimiter=r"\s+")
except Exception as e:
print(e)
return html.Div(["There was an error processing this file."])
return df
@app.callback(
Output("graph1", "figure"),
[Input("upload-data", "contents"), Input("upload-data", "filename")],
)
def update_table(contents, filename):
patched_children = Patch()
if contents:
contents = contents[0]
filename = filename[0]
df = parse_data(contents, filename)
Fig = html.Div(
[
dcc.Graph(go.Figure(
data=[
go.Scatter(
mode="markers",
x=df.iloc[:,0],
y=df.iloc[:,1],
showlegend=False
)
],
layout=go.Layout(
width=500,
height=500,
plot_bgcolor=colors["graphBackground"],
paper_bgcolor=colors["graphBackground"]
)))
]
)
patched_children.append(Fig)
return patched_children
if __name__ == "__main__":
app.run_server(debug=True)
请注意,补丁已应用于其相应的
Output
组件。
问题是第二个回调的输出:您希望在每次上传数据时向此输出添加一个图形(因此“修补”它),因此您需要定位容器 div 的
children
属性(而不是 figure
),就像上一个问题中的表格一样,以便您可以将新创建的图形附加(或前置)到图形列表中。
为了防止混淆,您可以首先将容器 div id 重命名为
'graph-container'
而不是 'graph1'
。
然后您可以按如下方式修复回调输出:
@app.callback(
Output("graph-container", "children"),
[Input("upload-data", "contents"), Input("upload-data", "filename")],
)
def update_table(contents, filename):
# ...