Switching between Dash application tabs clears the annotations on a canvas
I have created two Dash tabs for my application and each tab has a canvas with a background image. When I annotate one canvas by drawing, for example, rectangles, and then switch to the other tab and back to the initial one, the rectangles disappear but the background image remains in the canvas. How should I go about this issue?
Hey @nikandrovs94 (sorry for the slow response), could you please share here a minimal example reproducing the issue?
Thanks for your reply, @emmanuelle ! Please find the minimal code below. I use it to select an image for dash canvas background via file browser (you can pick any image you have to test it).
Just to clarify: The issue is that when I draw on the canvas in the first tab and then switch to the second tab and back to the first one, any lines that I drew are erased. It seems like the canvas is getting refreshed or something. Is there any way for the canvas to maintain users drawings while switching between dash tabs?
Thanks, Mike
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash_canvas import DashCanvas
from dash_canvas.utils import (array_to_data_url, parse_jsonstring, parse_jsonstring_line,
parse_jsonstring_rectangle, image_string_to_PILImage)
import sys, os, webbrowser, win32ui, win32con
from skimage import io
from PIL import Image
import numpy as np
def gui_select_file(start_dir=None):
'''
Opens a browser and returns the path to the selected file.
'''
fd = win32ui.CreateFileDialog(1)
fd.SetOFNTitle('Select contour file')
if fd.DoModal()==win32con.IDCANCEL:
sys.exit(1)
filepath = fd.GetPathName()
return filepath
filename = gui_select_file()
#Read the image file
image = Image.open(filename)
image_array = np.asarray(image)
shape = io.imread(filename, as_gray=True).shape
img_width = shape[1]
img_height = shape[0]
#Manually set the canvas dimensions
canvas_width = 800
canvas_scale = canvas_width/img_width
canvas_height = round(img_height*canvas_scale)
app = dash.Dash(__name__)
tabs_styles = {
'height': '50px',
'font-size': '22px',
'fontWeight': 'bold',
}
tab_style = {
'borderBottom': '2px solid #d6d6d6',
'padding': '6px',
'vertical-align': 'middle',
'align-items': 'center',
'justify-content': 'center',
}
tab_selected_style = {
'borderTop': '1px solid #d6d6d6',
'borderBottom': '1px solid #d6d6d6',
'backgroundColor': '#119DFF',
'color': 'white',
'padding': '6px'
}
app.config.suppress_callback_exceptions = True
app.layout = html.Div(
children=[
dcc.Tabs(
id='tabs',
style=tabs_styles,
children=[
#Calibration tab
dcc.Tab(
label='Calibration',
style=tab_style,
selected_style=tab_selected_style,
children=[
#Generate Dash canvas
DashCanvas(
lineWidth=2,
hide_buttons=['line', 'pencil'],
image_content=array_to_data_url(image_array),
lineColor='red',
width=canvas_width,
goButtonTitle='Extract Information'
)
]
),
#Calibration tab
dcc.Tab(
label='Measurements',
style=tab_style,
selected_style=tab_selected_style,
children=[
#Generate Dash canvas
DashCanvas(
lineWidth=2,
hide_buttons=['line', 'pencil'],
image_content=array_to_data_url(image_array),
lineColor='red',
width=canvas_width,
goButtonTitle='Extract Information'
)
]
)
]
)
]
)
my_port = 8050
if __name__ == '__main__':
url = "http://127.0.0.1:{}/".format(my_port)
webbrowser.open_new_tab(url)
app.server.run(port=my_port, host='127.0.0.1')