Update:
I found this thread https://github.com/plotly/dash/issues/71 and tried to follow the directions given there.
The key here is, as I thought the base64 encoding
So first I just upload all the file paths first via:
@app.callback(Output('image_list', 'component'),
[Input('Folder_submit', 'n_clicks')],
[State('Image_folder', 'value'),])
#calls the upload function, updating the global variable df and also storing
def update(n_clicks, folder):
find_dir='overlays'
image_dict={}
print(folder)
print('uploading...')
for root, dirs, files in os.walk(folder):
#print(dirs)
#looks in each folder from given path
#if folder is matching the KD pattern, the find_dir pattern and
#if there are csv files
if find_dir in root and len([x for x in files])!=0:
#print(find_dir)
#finds the csv files in the folder and adds them to a list
image_files=[x for x in files]
for img in image_files:
#join image and full path
img_path=os.path.join(root, img)
image_dict.update({img:img_path})
#print(image_dict)
print('images uploaded')
return image_dict
whereas the State is the path name given in a textfield
Because encoding all images immediately takes a huge amount of time, I was thinking to encode them only when they are needed.
They should be displayed when the corresponding track of a graph is hovered over.
This should be achieved by this callback:
@app.callback(Output('image-overlay', 'src'),
[Input('migration_data', 'hoverData')],
[State('image_list','component'),
State('image_type', 'children'),
State('Image_selector', 'value')])
def update_image_overlay(hoverData, image_dict, image_type, image_selector):
print(image_type)
#removing discrepancy between hover text and filename
exclusion=re.compile('_E+.*')
ID=hoverData['points'][0]['hovertext'].replace(re.search(exclusion, hoverData['points'][0]['hovertext']).group(),'')
#checking all dictionary filenames for containing the hovertext
for k in image_dict.keys():
if re.search(ID, k) !=None:
image_name=k
print(image_name)
print(ID)
#getting the image from the dictionary
image=image_dict[image_name]
#encode the image with base 64
encoded=base64.b64encode(open(image, 'rb').read())
return encoded.decode()
#break out of the loop when an image is found
break
I get all the print outs like:
None
t10_F7404_nuclei_B3_WB3_S7404_T10.tiff
WB3_S7404
when hovering over the data. However no image is displayed. I did once try with a single image being uploaded and statically being displayed once I hover over the graph, and this works. So i know where the image should be.
I tried to just
return encoded
but this did not work and give the error
*"dash.exceptions.InvalidCallbackReturnValue: *
The callback for <Output
image-overlay.src>
returned a value having type bytes
which is not JSON serializable.
The value in question is either the only value returned,
or is in the top level of the returned list,
and has string representation
‘`b’SUkqAAgAAAAPAP4ABAABAAAAAAAAAAABBAABAAAAAAQAAAEBBA[…]’
In general, Dash properties can only be
dash components, strings, dictionaries, numbers, None,
or lists of those.’
Which I find strange, because the string representation should be the same thing as when I upload the image with the upload button, shouldn’t it?
Cheers.
Edit:
I changed the return value to:
encoded=base64.b64encode(open(image, 'rb').read())
#return the encoded image
return 'data:image/png;base64,{}'.format(encoded.decode())
Which seems like it should work, if dash could display .tif files. Unfortunately it apparently can’t.
Since I really have no Idea about encoding of images and things like that:
Does anybody know if and how any of the many python modules for importing tifs can be used in dash plotly?