Pandas import error
还没有人认领这个 Issue。
- 主要语言
- Python
- 星标
- 18.8k
- 派生
- 2.8k
- 平均合并
- 16 小时 26 分钟
- 30 天内合并 PR
- 21
描述
A Dash user is seeing an error from pandas without ever directly importing pandas, just dash, plotly, and numpy. https://community.plotly.com/t/callback-error-when-plotting-multiple-graph-objects/38756
The error occurs inside plotly when the Dash app tries to render one of the plots in a callback:
Traceback (most recent call last):
File "/Users/alex/plotly/fiddle/f.py", line 74, in update_dist_plot
"data": [go.Bar(x=bins, y=counts)],
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/plotly/graph_objs/__init__.py", line 93149, in __init__
self["x"] = x if x is not None else _v
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/plotly/basedatatypes.py", line 3490, in __setitem__
self._set_prop(prop, value)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/plotly/basedatatypes.py", line 3772, in _set_prop
val = validator.validate_coerce(val)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_plotly_utils/basevalidators.py", line 385, in validate_coerce
v = copy_to_readonly_numpy_array(v)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_plotly_utils/basevalidators.py", line 93, in copy_to_readonly_numpy_array
if pd and isinstance(v, (pd.Series, pd.Index)):
AttributeError: module 'pandas' has no attribute 'Series'
That's the error I see - the OP's error message is a little more extensive, which is a little funny because we both report pandas v1.0.3
AttributeError: partially initialized module ‘pandas’ has no attribute ‘Series’ (most likely due to a circular import)
I can reproduce locally with this app:
import dash_core_components as dcc
import dash_html_components as html
from dash import Dash
from dash.dependencies import Input, Output
import plotly.graph_objs as go
import numpy as np
app = Dash(__name__)
app.layout = html.Div(
[
html.Div(
[
html.Br(),
html.Label("Plotting Options"),
dcc.RadioItems(
id="trunk-angle-radio",
options=[
{"label": "Sagittal", "value": "Sagittal"},
{"label": "Lateral", "value": "Lateral"},
{"label": "Twist", "value": "Twist"},
],
value="Sagittal",
),
]
),
html.Div(
[
html.Div(
[dcc.Graph(id="trunk-angle-plot")],
style={"width": "48%", "display": "inline-block"},
),
html.Div(
[dcc.Graph(id="trunk-angle-dist")],
style={"width": "48%", "display": "inline-block", "float": "right"},
),
]
),
html.Div(
[
html.Label("Data Statistics"),
html.Div(id="data-stats-div", style={"padding": 10}),
]
),
]
)
@app.callback(
Output("trunk-angle-plot", "figure"), [Input("trunk-angle-radio", "value")]
)
def update_angle_plot(radio_option):
(x, y) = get_trunk_angles(radio_option)
fig = {
"data": [go.Scatter(x=x, y=y, mode="lines+markers")],
"layout": go.Layout(
title="Trunk Angle Time Series Plot",
xaxis={"title": "Time (sec)"},
yaxis={"title": "Degrees"},
),
}
return fig
@app.callback(
Output("trunk-angle-dist", "figure"), [Input("trunk-angle-radio", "value")]
)
def update_dist_plot(radio_option):
(x, y) = get_trunk_angles(radio_option)
counts, bins = np.histogram(y, bins=range(-90, 91, 30))
bins = bins + (bins[1] - bins[0]) / 2
# print(counts, bins)
fig = {
"data": [go.Bar(x=bins, y=counts)],
"layout": go.Layout(
title="Trunk Angle Distributions",
xaxis={
"title": "Bin midpoint (degrees)",
"tickmode": "array",
"tickvals": bins,
"ticktext": [str(int(bin)) for bin in bins],
},
yaxis={"title": "Percentage of time"},
),
}
return fig
@app.callback(
Output("data-stats-div", "children"), [Input("trunk-angle-radio", "value")]
)
def update_stats(radio_option):
(x, y) = get_trunk_angles(radio_option)
stats_div = [
html.Div("Minimum: {}".format(np.min(y)), id="trunk-angle-dist-min"),
html.Div("Maximum: {}".format(np.max(y)), id="trunk-angle-dist-max"),
html.Div("Mean: {:.2f}".format(np.mean(y)), id="trunk-angle-dist-mean"),
html.Div(
"Standard Deviation: {:.2f}".format(np.std(y)), id="trunk-angle-dist-std"
),
html.Div(
"Range: {}".format(np.max(y) - np.min(y)), id="trunk-angle-dist-range"
),
]
return stats_div
def get_trunk_angles(radio_option):
dummy_x = np.linspace(0, 50, 101)
if radio_option == "Sagittal":
dummy_y = np.random.randint(-90, 90, 101)
elif radio_option == "Lateral":
dummy_y = np.random.randint(-90, 90, 101)
elif radio_option == "Twist":
dummy_y = np.random.randint(-90, 90, 101)
return (dummy_x, dummy_y)
if __name__ == "__main__":
app.run_server(debug=True)
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
复现提供的 Dash 应用,并从 plotly/basedatatypes.py 和 _plotly_utils/basevalidators.py 中的 traceback 位置开始,尤其关注 update_dist_plot 和 copy_to_readonly_numpy_array。追踪在构造 go.Bar 时 pandas 缺少 Series 的原因,然后验证 callback 在没有报告的 AttributeError 的情况下能够渲染。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- numpy, pandas, python
- 领域
- data-visualization
- Issue 类型
- 缺陷
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 停滞
- 描述清晰度
- 需要澄清
- 新手友好度
- 25/100