[英]Python: Dash, Plotly, and Jupyter Notebook: Use a WSGI server instead
I am working on some plotly image processing for my work.我正在为我的工作进行一些 plotly 图像处理。 I have been using matplotlib but need something more interactive, so I switched to dash and plotly.我一直在使用 matplotlib 但需要更具交互性的东西,所以我切换到破折号和 plotly。 My goal is for people on my team to be able to draw a shape around certain parts of an image and return pixel values.我的目标是让我的团队成员能够在图像的某些部分周围绘制形状并返回像素值。
I am using this documentation and want a similar result: https://dash.plotly.com/annotations ;我正在使用此文档并希望得到类似的结果: https://dash.plotly.com/annotations ; specifically "Draw a path to show the histogram of the ROI"特别是“绘制路径以显示 ROI 的直方图”
Code:代码:
import numpy as np
import plotly.express as px
from dash import Dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
from skimage import data, draw #yes necessary
from scipy import ndimage
import os, glob
from skimage import io
imagePath = os.path.join('.','examples')
filename = glob.glob(os.path.join(imagePath,'IMG_0650_6.tif'))[0]
moon = io.imread(filename)
#imagePath = os.path.join('.','examples')
#imageName = glob.glob(os.path.join(imagePath,'IMG_0650_6.tif'))[0]
def path_to_indices(path):
"""From SVG path to numpy array of coordinates, each row being a (row, col) point
"""
indices_str = [
el.replace("M", "").replace("Z", "").split(",") for el in path.split("L")
]
return np.rint(np.array(indices_str, dtype=float)).astype(np.int)
def path_to_mask(path, shape):
"""From SVG path to a boolean array where all pixels enclosed by the path
are True, and the other pixels are False.
"""
cols, rows = path_to_indices(path).T
rr, cc = draw.polygon(rows, cols)
mask = np.zeros(shape, dtype=np.bool)
mask[rr, cc] = True
mask = ndimage.binary_fill_holes(mask)
return mask
img = data.moon()
#print(img)
#print(type(img))
fig = px.imshow(img, binary_string=True)
fig.update_layout(dragmode="drawclosedpath")
fig_hist = px.histogram(img.ravel())
app = Dash(__name__)
app.layout = html.Div(
[
html.H3("Draw a path to show the histogram of the ROI"),
html.Div(
[dcc.Graph(id="graph-camera", figure=fig),],
style={"width": "60%", "display": "inline-block", "padding": "0 0"},
),
html.Div(
[dcc.Graph(id="graph-histogram", figure=fig_hist),],
style={"width": "40%", "display": "inline-block", "padding": "0 0"},
),
]
)
@app.callback(
Output("graph-histogram", "figure"),
Input("graph-camera", "relayoutData"),
prevent_initial_call=True,
)
def on_new_annotation(relayout_data):
if "shapes" in relayout_data:
last_shape = relayout_data["shapes"][-1]
mask = path_to_mask(last_shape["path"], img.shape)
return px.histogram(img[mask])
else:
return dash.no_update
if __name__ == "__main__":
app.run_server(debug=True)
This returns the following error:这将返回以下错误:
Dash is running on http://127.0.0.1:8050/ Dash 在http://127.0.0.1:8050/上运行
Traceback:追溯:
Traceback (most recent call last):
File "/Users/anthea/opt/anaconda3/lib/python3.9/site-packages/ipykernel_launcher.py", line 16, in <module>
app.launch_new_instance()
File "/Users/anthea/opt/anaconda3/lib/python3.9/site-packages/traitlets/config/application.py", line 845, in launch_instance
app.initialize(argv)
File "/Users/anthea/opt/anaconda3/lib/python3.9/site-packages/traitlets/config/application.py", line 88, in inner
return method(app, *args, **kwargs)
File "/Users/anthea/opt/anaconda3/lib/python3.9/site-packages/ipykernel/kernelapp.py", line 632, in initialize
self.init_sockets()
File "/Users/anthea/opt/anaconda3/lib/python3.9/site-packages/ipykernel/kernelapp.py", line 282, in init_sockets
self.shell_port = self._bind_socket(self.shell_socket, self.shell_port)
File "/Users/anthea/opt/anaconda3/lib/python3.9/site-packages/ipykernel/kernelapp.py", line 229, in _bind_socket
return self._try_bind_socket(s, port)
File "/Users/anthea/opt/anaconda3/lib/python3.9/site-packages/ipykernel/kernelapp.py", line 205, in _try_bind_socket
s.bind("tcp://%s:%i" % (self.ip, port))
File "/Users/anthea/opt/anaconda3/lib/python3.9/site-packages/zmq/sugar/socket.py", line 208, in bind
super().bind(addr)
File "zmq/backend/cython/socket.pyx", line 540, in zmq.backend.cython.socket.Socket.bind
File "zmq/backend/cython/checkrc.pxd", line 28, in zmq.backend.cython.checkrc._check_rc
zmq.error.ZMQError: Address already in use
Solution Attempts:解决方案尝试:
I've consulted similar issues on here and tried reassigning 8050 to 1337, which was ineffective.我在这里咨询过类似的问题,并尝试将 8050 重新分配给 1337,但效果不佳。
when I had the same error I just tried to shutdown the other notebooks which are using the same Address 'http://127.0.0.1:8050/'当我遇到同样的错误时,我只是尝试关闭使用相同地址“http://127.0.0.1:8050/”的其他笔记本
Other solution also worked for me, I changed the default port parameter其他解决方案也对我有用,我更改了默认端口参数
if __name__ == '__main__':
app.run_server(port=8051)
I had the same problem and no amount of searching gave me an answer that solved my problem.我有同样的问题,没有多少搜索给我一个解决我问题的答案。
When I changed my code to this:当我将代码更改为:
if __name__ == "__main__":
app.run_server(debug=False)
It ran fine.它运行良好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.