def test_dbm3001_selection_type(dash_duo): app = dash.Dash(__name__) app.layout = html.Div( simple_app_layout( dash_bio.Molecule3dViewer(id=_COMPONENT_ID, modelData=_model_data, styles=_styles_data))) simple_app_callback(app, dash_duo, component_id=_COMPONENT_ID, test_prop_name='selectionType', test_prop_value='chain', prop_value_type='string') # find and click on one of the DNA strands mol3d = dash_duo.find_element('#test-mol3d canvas') ac = ActionChains(dash_duo.driver) ac.move_to_element(mol3d).move_by_offset(0, -50).click().perform() dash_duo.wait_for_element_by_css_selector('.molecule-3d') dash_duo.percy_snapshot('test-mol3d_selectionType_chain' + generate_identifier(), convert_canvases=True)
def update_3dviewer(callback_hoverdict, periodic_repetition_structure, default=-1): global callback_hoverdict_global run_update = True if periodic_repetition_structure == None: periodic_repetition_structure = '(0,1) (0,1) (0,1)' elif not periodic_repetition_structure.count( '(') == 3 or not periodic_repetition_structure.count(')') == 3: run_update = False if not run_update: raise Exception('no update required') if not callback_hoverdict == None: callback_hoverdict_global = callback_hoverdict if callback_hoverdict_global == []: atoms_id = 0 else: atoms_id = callback_hoverdict_global["points"][0]["pointNumber"] modelData, shapes, atoms_current = return_modelData_atoms( atoms_id, periodic_repetition_str=periodic_repetition_structure) styles = helpers.return_style(atoms_current) view = dash_bio.Molecule3dViewer( id='3d-viewer', styles=styles, shapes=shapes, modelData=modelData) #modelData) #])), return view
def use_upload( contents, demostr, mol_style, color_style, mt, custom_colors ): if demostr is not None: copy2(demostr, './str.pdb') fname = './str.pdb' elif contents is not None and demostr is None: try: content_type, content_string = str(contents).split(',') decoded_contents = base64.b64decode( content_string).decode("UTF-8") f = tempfile.NamedTemporaryFile( suffix=".pdb", delete=False, mode='w+') f.write(decoded_contents) fname = f.name f.close() except AttributeError: pass else: return 'demostr and contents are none' # Create the model data from the decoded contents modata = parser.create_data(fname) fmodel = files_data_style(modata) with open(fmodel) as fm: mdata = json.load(fm) # Create the cartoon style from the decoded contents datstyle = sparser.create_style(fname, mol_style, color_style, **custom_colors) fstyle = files_data_style(datstyle) with open(fstyle) as sf: data_style = json.load(sf) # Delete all the temporary files that were created for x in [fname, fmodel, fstyle]: if os.path.isfile(x): os.unlink(x) else: pass # Return the new molecule visualization container return dash_bio.Molecule3dViewer( id='mol-3d', selectionType='atom', modelData=mdata, styles=data_style, selectedAtomIds=[], backgroundOpacity='0', atomLabelsShown=False, )
def update_3d_viewer_on_hover(hover_data_dict, data, periodic_repetition_str): """ Update the visualiser on a hover event. If the event is None, then no change occurs. Note: Initialisation is handled by the change of data callback. Default decorator: @app.callback(Output('div-3dviewer', 'children'), [Input('graph', 'clickData'), Input('app-memory', 'data'), Input('input_periodic_repetition_structure', 'value')]) :param hover_data_dict: :param data: :param periodic_repetition_str: :return: Args: periodic_repetition_str: periodic_repetition_str: """ # decide which one triggered the event ctx = callback_context point_index = 0 if ctx.triggered: triggr_obj_name = ctx.triggered[0]['prop_id'].split('.')[0] if triggr_obj_name == 'app-memory': pass elif triggr_obj_name == 'graph': if hover_data_dict is None: raise PreventUpdate print('DEBUG update 3d viewer with dict: \n\t{}'.format(hover_data_dict)) try: point_index = hover_data_dict['points'][0]['pointNumber'] except TypeError: point_index = 0 else: print('DEBUG: update of 3d viewer prevented by callback_context.triggered=False') raise PreventUpdate # The visualiseable atoms do not exist on the initial call, so just an empty 3D viewer is enough try: viewer_data = visualiser.construct_3d_view_data(data, point_index, periodic_repetition_str) except KeyError: viewer_data = dict() # noinspection PyUnresolvedReferences return dash_bio.Molecule3dViewer(**viewer_data)
def test_dbm3002_rotate(dash_duo): app = dash.Dash(__name__) app.layout = html.Div([ dash_bio.Molecule3dViewer(id=_COMPONENT_ID, modelData=_model_data, styles=_styles_data) ]) dash_duo.start_server(app) dash_duo.wait_for_element('#' + _COMPONENT_ID) mol3d = dash_duo.find_element('#' + _COMPONENT_ID + ' canvas') ac = ActionChains(dash_duo.driver) ac.drag_and_drop_by_offset(mol3d, 100, 50).perform() dash_duo.percy_snapshot('test-mol3d_rotate')
def test_dbm3003_selected_atom_ids(dash_duo): app = dash.Dash(__name__) app.layout = html.Div( simple_app_layout( dash_bio.Molecule3dViewer(id=_COMPONENT_ID, modelData=_model_data, styles=_styles_data))) simple_app_callback(app, dash_duo, component_id=_COMPONENT_ID, test_prop_name='selectedAtomIds', test_prop_value=json.dumps([1306, 1371, 1339, 1404]), prop_value_type='list', validation_fn=lambda x: json.dumps(x) == json.dumps( [1306, 1371, 1339, 1404]), take_snapshot=True)
def test_dbm3004_labels(dash_duo): app = dash.Dash(__name__) app.layout = html.Div([ dash_bio.Molecule3dViewer(id=_COMPONENT_ID, modelData=_model_data, styles=_styles_data, labels=[{ "text": "first_text", "fontColor": "red" }, { "text": "second_text", "backgroundColor": "blue", "position": { "x": 10, "y": -10, "z": 0 } }]), html.Div(id="labels-output") ]) @app.callback( Output(component_id='labels-output', component_property='children'), Input(component_id=_COMPONENT_ID, component_property='labels')) def update_output_div(labels): return labels[0]['text'] dash_duo.start_server(app, dev_tools_props_check=True) dash_duo.wait_for_element('#' + _COMPONENT_ID) dash_duo.wait_for_text_to_equal('#labels-output', 'first_text') dash_duo.percy_snapshot('test-mol3d_labels' + generate_identifier(), convert_canvases=True)
df = pd.read_excel("data/Gordon-2002_LungCancer.xlsx", index_col=0, skiprows=[1]) df = df.iloc[:100, :7] # slicing dataframe for simpler heatmap data = df.values # dashboard layout app = dash.Dash("Example", external_stylesheets=[dbc.themes.DARKLY]) app.title = "Example" app.layout = dbc.Tabs([ dbc.Tab( html.Div([ dashbio.Molecule3dViewer( id="my-dashbio-molecule3d", styles=styles_data, modelData=model_data, ), "Selection data", html.Hr(), html.Div(id="molecule3d-output"), ]), label="3D protein", ), dbc.Tab( dcc.Graph(figure=dashbio.Clustergram( data=data, hidden_labels=["row"], height=900, width=1400, column_labels=list(df.columns.values),
class ReactionViewerApp(DashAppBase): """Create a Dash app.""" layout = html.Div( [ dbc.Alert( "The app is in an alpha state and may contain incorrect results.", color="warning", ), ### Header dbc.Row([dbc.Col([html.H3("Benchmark Dataset Viewer")])]), ### Main selectors dbc.Row([ dbc.Col([dbc.Label("Choose a dataset:")], width=3), dbc.Col([ dcc.Dropdown( id="available-rds", options=list_collections(), value="S22", ) ]), ]), dbc.Row([ dbc.Col([dbc.Label("Select methods to display:")], width=3), dbc.Col([ dcc.Dropdown( id="rds-available-methods", options=[], multi=True) ]), ]), dbc.Row([ dbc.Col([dbc.Label("Select basis sets to display:")], width=3), dbc.Col([ dcc.Dropdown( id="rds-available-basis", options=[], multi=True) ]), # multi=True, ]), ### Radio Options dbc.Row( [ dbc.Col([ dbc.Label("Group by:"), # dbc.ButtonGroup( # [ # dbc.Button("None", color="primary", active=True), # dbc.Button("Method", color="primary"), # dbc.Button("Basis", color="primary"), # dbc.Button("D3", color="primary"), # ] # ), dbc.RadioItems( id="rds-groupby", options=[ { "label": "None", "value": "none" }, { "label": "Method", "value": "method" }, { "label": "Basis", "value": "basis" }, { "label": "D3", "value": "d3" }, ], # className="btn-group btn-group-toggle", # inputClassName="form-check-input", # labelClassName="btn btn-primary form-check-label", # labelCheckedClassName="active", # custom=False, switch=True, value="none", # inline=True, ), ]), dbc.Col([ dbc.Label("Metric:"), dbc.RadioItems( id="rds-metric", options=[ { "label": "UE", "value": "UE" }, { "label": "URE", "value": "URE" }, ], value="UE", switch=True, # inline=True, ), ]), dbc.Col([ dbc.Label("Plot type:"), dbc.RadioItems( id="rds-kind", options=[ { "label": "Bar", "value": "bar" }, { "label": "Violin", "value": "violin" }, ], value="bar", # inline=True, switch=True, ), ]), dbc.Col([ dbc.Label("Counterpoise correction:"), dbc.RadioItems( id="rds-stoich", options=[ { "label": "CP", "value": "cp" }, { "label": "noCP", "value": "default" }, ], value="cp", # inline=True, switch=True, ), ]), ], className="my-3", ), ### Primary data visualizer dbc.Card( [ dbc.CardHeader(id="info-dataset-name", style=CARD_HEADER_STYLE), dbc.Toast( [html.P(id="graph-toast-error-message")], id="graph-toast-error", header="An error occured!", icon="danger", dismissable=True, is_open=False, style={"max-width": "100%"}, ), dcc.Loading( id="loading-1", children=[dcc.Graph(id="primary-graph")], type="default", style={"height": "450px"}, ), ], className="mb-3", ), ### Molecule Explorer dbc.Card( [ dbc.CardHeader("Molecule Explorer", style=CARD_HEADER_STYLE), dcc.Dropdown( id="available-molecules", options=[], multi=False, className="p-2", ), dbc.Toast( [html.P(id="molecule-toast-error-message")], id="molecule-toast-error", header="An error occured!", icon="danger", dismissable=True, is_open=False, style={"max-width": "100%"}, ), dcc.Loading(id="loading-2", children=[ dashbio.Molecule3dViewer( id="dash-bio-3d", styles={}, modelData={ "atoms": [], "bonds": [] }, ) ], type="default", style={"height": "500px"} # styles=styles_data, modelData=model_data) ), ], className="mb-3", ), ### Info dbc.Card([ dbc.CardHeader("Database Information", style=CARD_HEADER_STYLE), dbc.ListGroup(id="dataset-information", flush=True), ]), ], className="container py-3", ) def get_layout(self, dashapp): return self.layout def register_callbacks(self, dashapp): @dashapp.callback( [ Output("rds-available-methods", "options"), Output("rds-available-basis", "options"), Output("info-dataset-name", "children"), Output("available-molecules", "options"), Output("available-molecules", "value"), Output("dataset-information", "children"), ], [Input("available-rds", "value")], ) def display_value(value): ds = get_collection_metadata(value) bases = get_history_values(value, "basis") try: bases.remove({"label": "None", "value": "None"}) except: pass try: tmp = ds.data.metadata["citations"][0]["acs_citation"] tmp = tmp.replace("&", "&") authors, second = tmp.split("<em>") emph, remaining = second.split("</em>") bold, remaining = remaining.replace("<b>", "").split("</b>") italics, remaining = remaining.replace("<i>", "").split("</i>") doi = ds.data.metadata["citations"][0]["doi"] citation = html.P([ html.H5("Citation:"), html.P([ authors, html.Em(emph), html.B(bold), html.I(italics), remaining, ]), html.P([ html.B("DOI: "), html.A(doi, href=f"https://doi.org/{doi}", target="_blank"), ]), ]) # citation = citation.replace("</em>", "*").replace( # "<em>", "*" # ) # Italics 1 # citation = citation.replace("</i>", "*").replace( # "<i>", "*" # ) # Italics 2 # citation = citation.replace("</b>", "**").replace("<b>", "**") # Bold # citation = citation.replace(", ***", "*, **").replace( # "***, ", "**, *" # ) # HTML vs Markdown corrections except Exception as exc: logger.error(str(exc)) citation = html.P([ html.H5("Citation:"), html.I("No information available.") ]) # dedent( # f""" # ## Citation: # *No information available.* # """ # ) mqcas_help = html.P([ "We are still filling in data and expanding these Webapps. If you have features suggestions or bug reports please file them ", html.A( "here", href= "https://github.com/MolSSI/QCArchiveWebapps/issues/new/choose", target="_blank", ), " or if you wish to expand the datasets, methods, or bases please open an issue ", html.A( "here", href="https://github.com/MolSSI/MQCAS/issues/new/choose", target="_blank", ), ".", ]) dataset_info = [ dbc.ListGroupItem(x) for x in [citation, mqcas_help] ] save_access( page="reaction_datasets", access_type="dataset_query", dataset_name=value, ) mol_index = [{"label": x, "value": x} for x in ds.get_index()] return ( get_history_values(value, "method"), bases, f"{ds.data.name}: {ds.data.tagline}", mol_index, mol_index[0]["value"], dataset_info, ) @dashapp.callback( [ Output("primary-graph", "figure"), Output("graph-toast-error", "is_open"), Output("graph-toast-error-message", "children"), ], [ Input("available-rds", "value"), Input("rds-available-methods", "value"), Input("rds-available-basis", "value"), Input("rds-groupby", "value"), Input("rds-metric", "value"), Input("rds-kind", "value"), Input("rds-stoich", "value"), ], ) def show_graph(dataset, method, basis, groupby, metric, kind, stoich): # Incomplete data, nothing to return if (method is None) or (basis is None): print("") return {}, False, None save_access( page="reaction_datasets", access_type="graph_query", dataset_name=dataset, method=method, basis=basis, groupby=groupby, metric=metric, kind=kind, stoich=stoich, ) try: with collection_df_manager(dataset) as ds: if groupby == "none": groupby = None t = time.time() fig = ds.visualize( method=method, basis=basis + ["None"], groupby=groupby, metric=metric, kind=kind, stoich=stoich, return_figure=True, ) fig.update_layout(title_text=None, margin={ "t": 25, "b": 25 }) logger.debug( f"Built {dataset} graph in {time.time() - t}s.") return fig, False, None except Exception as exc: print(traceback.format_exc()) tb = "\n".join( traceback.format_exc(limit=0, chain=False).splitlines()[1:]) return {}, True, tb @dashapp.callback( [Output("rds-stoich", "options"), Output("rds-stoich", "value")], [Input("available-rds", "value")], [State("rds-stoich", "value")], ) def toggle_counterpoise(dataset, current_stoich): ds = get_collection_metadata(dataset) if "cp" in ds.valid_stoich(): return ( [ { "label": "CP", "value": "cp" }, { "label": "noCP", "value": "default" }, ], current_stoich, ) else: return ( [{ "label": "N/A", "value": "default", "disabled": True }], "default", ) @dashapp.callback( [ Output("dash-bio-3d", "modelData"), Output("dash-bio-3d", "styles"), Output("molecule-toast-error", "is_open"), Output("molecule-toast-error-message", "children"), ], [Input("available-molecules", "value")], [State("available-rds", "value")], ) def show_molecule(molecule, dataset): blank_return = ({"atoms": [], "bonds": []}, {}) if molecule is None: return blank_return + (False, None) try: key = f"rd_df_molecule_cache_{dataset}_{molecule}" d3moljs_data = cache.get(key) if d3moljs_data is None: ds = get_collection_metadata(dataset) mol = ds.get_molecules(subset=molecule).iloc[0, 0] d3moljs_data = molecule_to_d3moljs(mol) cache.set(key, d3moljs_data, timeout=CACHE_TIMEOUT) model_data, style_data = d3moljs_data return model_data, style_data, False, None except: print(traceback.format_exc()) tb = "\n".join( traceback.format_exc(limit=0, chain=False).splitlines()[1:]) return blank_return + (True, tb)
def main(config_filename, extended_xyz_file, mode, title, soap_cutoff_radius, marker_radius, height_graph, width_graph): global callback_hoverdict_global, list_hovertexts if config_filename != 'None': # read config if given config = configparser.ConfigParser() config.read(config_filename) extended_xyz_file = config['Basic']['extended_xyz_file'] mode = config['Basic']['mode'] title = config['Basic']['title'] soap_cutoff_radius = config['Basic']['soap_cutoff_radius'] marker_radius = config['Basic']['marker_radius'] height_graph = int(config['Basic']['height_graph']) width_graph = int(config['Basic']['height_graph']) # read atoms atoms = ase.io.read(extended_xyz_file, ':') #[atoms[i].set_pbc(False) for i in range(len(atoms))] # Setup of the dataframes and atom/molecular infos for the 3D-Viewer shapes = [] dataframe = helpers.build_dataframe_features(atoms, mode=mode) if mode == 'atomic': c_first_marker = atoms[0].get_positions()[0] system_ids = dataframe['system_ids'] atomic_numbers = dataframe['atomic_numbers'] dataframe.drop(['atomic_numbers', 'system_ids'], axis=1, inplace=True) # add a periodic box if needed shapes += helpers.get_periodic_box_shape_dict(atoms[0]) # Initial data for the graph and 3D viewer default_style = helpers.return_style(atoms[0], default=0) x_default = dataframe[dataframe.columns.tolist()[0]].tolist() y_default = dataframe[dataframe.columns.tolist()[1]].tolist() size_default = dataframe[dataframe.columns.tolist()[2]].tolist() size_default = np.array(size_default) size_default = list(size_default - min(size_default)) # cant be smaller than 0 color_default = dataframe[dataframe.columns.tolist()[3]].tolist() colorbar_title = dataframe.columns.tolist()[3] style_dropdown = { 'height': '35px', 'width': '100%', 'display': 'inline-block' } list_hovertexts = helpers.get_hoverinfo_texts(dataframe) # Setup of app app = dash.Dash(__name__) app.layout = html.Div( children=[ html.H3(children=title), html.Div([ html.Span([ "x-axis", html.Br(), dcc.Dropdown(id='x-axis', options=[{ 'label': '{}'.format(l), 'value': i } for i, l in enumerate(dataframe.columns)], value=0, style=style_dropdown) ], className='app__dropdown'), html.Span([ 'y-axis', dcc.Dropdown(id='y-axis', options=[{ 'label': '{}'.format(l), 'value': i } for i, l in enumerate(dataframe.columns)], value=1, style=style_dropdown) ], className='app__dropdown'), html.Span([ "marker-size", dcc.Dropdown(id='marker_size', options=[{ 'label': '{}'.format(l), 'value': i } for i, l in enumerate(dataframe.columns)], value=2, style=style_dropdown) ], className='app__dropdown'), html.Span([ "marker-color", dcc.Dropdown(id='marker_color', options=[{ 'label': '{}'.format(l), 'value': i } for i, l in enumerate(dataframe.columns)], value=3, style=style_dropdown) ], className='app__dropdown'), html.Span([ 'marker-opacity', html.Br(), dcc.Input(id='marker_opacity', type='text', placeholder='marker opacity (0 to 1)') ], className='app__dropdown'), html.Span([ 'colorscale', html.Br(), dcc.Input(id='colorscale', type='text', placeholder='colormap name') ], className='app__dropdown'), ], className="app__controls"), html.Div([ html.Span([ "marker-size-range", dcc.RangeSlider( id='marker_size_range', min=1, max=100, step=0.1, value=[5, 50], marks={s: s for s in range(0, 101, 10)}, allowCross=False, ) ], className='app__slider'), html.Span([ "marker-size-limits", dcc.RangeSlider( id='marker_size_limits', min=0, max=100, step=0.1, value=[0, 100], marks={p: '{}%'.format(p) for p in range(0, 101, 10)}, allowCross=False, ) ], className='app__slider'), html.Span([ "marker-color-limits", dcc.RangeSlider( id='marker_color_limits', min=0, max=100, step=0.1, value=[0, 100], marks={p: '{}%'.format(p) for p in range(0, 101, 10)}, allowCross=False, ) ], className='app__slider'), html.Br(), html.Br(), ], className='app__controls'), # placeholder by graph, now filled in by callback on startup html.Div( [dcc.Graph(id='graph', figure={ 'data': [], 'layout': {} })], className='app__container_scatter'), html.Div([ html.Span([ 'Periodic repetition of structure: ', dcc.Input(id='periodic_repetition_structure', type='text', placeholder='(0,1) (0,1) (0,1)') ], className='app__remarks_viewer'), dcc.Markdown(''' **Axis:** x : red y : green z : blue **Green sphere:** Selected atom marker. **Gray wireframe:** SOAP cutoff. **Mouse-Navigation:** *Mouse:* Rotate, *Ctrl+Mouse:* Translate, *Shift+Mouse:* Zoom''', className='app__remarks_viewer'), dcc.Loading( html.Div([ dash_bio.Molecule3dViewer( id='3d-viewer', styles=default_style, shapes=shapes, modelData=json.loads(helpers.ase2json(atoms[0]))) ], id='div-3dviewer')), ], className='app__container_3dmolviewer', style={ 'height': height_graph, 'width_graph': width_graph }), ], className='app-body') # Callbacks that update the viewer @app.callback(dash.dependencies.Output('graph', 'figure'), [ dash.dependencies.Input('x-axis', 'value'), dash.dependencies.Input('y-axis', 'value'), dash.dependencies.Input('marker_size', 'value'), dash.dependencies.Input('marker_size_range', 'value'), dash.dependencies.Input('marker_size_limits', 'value'), dash.dependencies.Input('marker_color', 'value'), dash.dependencies.Input('marker_color_limits', 'value'), dash.dependencies.Input('colorscale', 'value'), dash.dependencies.Input('marker_opacity', 'value'), ]) def update_graph(x_axis, y_axis, marker_size, marker_size_range, marker_size_limits, marker_color, marker_color_limits, colorscale, marker_opacity): global list_hovertexts color_new = dataframe[dataframe.columns.tolist()[marker_color]] # color limits color_new = copy.copy( dataframe[dataframe.columns.tolist()[marker_color]]) color_span = np.abs(np.max(color_new) - np.min(color_new)) color_new_lower = np.min( color_new) + color_span / 100. * marker_color_limits[0] color_new_upper = np.min( color_new) + color_span / 100. * marker_color_limits[1] indices_in_limits = np.asarray([ idx for idx, val in enumerate(color_new) if color_new_lower <= val <= color_new_upper ]) color_new_min = np.min(color_new) color_new_max = np.max(color_new) color_new_lower = color_new_min + color_span / 100. * marker_color_limits[ 0] color_new_upper = color_new_min + color_span / 100. * marker_color_limits[ 1] size_new = dataframe[dataframe.columns.tolist()[marker_size]].tolist() size_new = np.array(size_new) size_new = size_new - min(size_new) # cant be smaller than 0 #opacity if marker_opacity == None: marker_opacity = 1.0 else: try: # convert to float here and check if value was valid marker_opacity = float(marker_opacity) if marker_opacity < 0. or marker_opacity > 1.: raise ValueError except ValueError: print( 'Marker opacity set: {} ; Invalid, set to 1.0 be default.'. format(marker_opacity)) marker_opacity = 1.0 size_new = copy.copy( dataframe[dataframe.columns.tolist()[marker_size]].tolist()) size_new = np.array(size_new) size_new = size_new - np.min(size_new) # cant be smaller than 0 size_new_range = np.max(size_new) size_new_lower = size_new_range / 100. * marker_size_limits[0] size_new_upper = size_new_range / 100. * marker_size_limits[1] try: for idx, size_new_i in enumerate(size_new): if size_new_i < size_new_lower: size_new[idx] = marker_size_range[0] elif size_new_i > size_new_upper: size_new[idx] = marker_size_range[1] else: size_new[idx] = _get_new_sizes( size_new_i, [size_new_lower, size_new_upper], marker_size_range) except: print( 'Error in scaling marker sizes. Using `30` for all data points instead.' ) size_new = np.asarray([30] * len(size_new)) size_new_tmp = [] for idx, size_i in enumerate(size_new): if idx in indices_in_limits: size_new_tmp.append(size_i) else: size_new_tmp.append(0) size_new = np.asarray(size_new_tmp) return { 'data': [ go.Scattergl( x=dataframe[dataframe.columns.tolist()[x_axis]].tolist(), y=dataframe[dataframe.columns.tolist()[y_axis]].tolist(), mode='markers', hovertext=list_hovertexts, marker={ 'color': color_new, 'colorscale': 'Viridis' if colorscale is None or colorscale == '' else colorscale, 'size': size_new, 'colorbar': { 'title': dataframe.columns.tolist()[marker_color] }, 'opacity': float(marker_opacity), 'cmin': color_new_lower, 'cmax': color_new_upper, 'line': { 'color': 'rgb(0, 116, 217)', 'width': 0.5 } }, name='TODO', ) ], 'layout': go.Layout( height=height_graph, hovermode='closest', # title = 'Data Visualization' xaxis={ 'zeroline': False, 'showgrid': False, 'ticks': 'outside', 'automargin': True, 'showline': True, 'mirror': True, 'title': dataframe.columns.tolist()[x_axis] }, yaxis={ 'zeroline': False, 'showgrid': False, 'ticks': 'outside', 'automargin': True, 'showline': True, 'mirror': True, 'title': dataframe.columns.tolist()[y_axis] }) } def _get_new_sizes(value, value_range, size_range): """Map ``value`` to a range within ``size_range`` in a linear fashion.""" slope = (size_range[1] - size_range[0]) / float(value_range[1] - value_range[0]) return size_range[0] + slope * (value - value_range[0]) def return_shape_callback(atoms_current, pos_marker=None, default=-1, shift_cell=np.array([0., 0., 0.])): shapes = [] if isinstance(pos_marker, np.ndarray) or isinstance(pos_marker, list): shapes = [{ 'type': 'Sphere', "color": "gray", "center": { 'x': pos_marker[0], 'y': pos_marker[1], 'z': pos_marker[2] }, "radius": soap_cutoff_radius, 'wireframe': True }, { 'type': 'Sphere', "color": "green", "center": { 'x': pos_marker[0], 'y': pos_marker[1], 'z': pos_marker[2] }, "radius": marker_radius }] shape_box = helpers.get_periodic_box_shape_dict( atoms_current, shift_cell) shapes += shape_box return shapes def return_modelData_atoms(atoms_id, periodic_repetition_str='(0,1) (0,1) (0,1)'): if mode == "atomic": atoms_current = atoms[system_ids[atoms_id]] pos_marker = atoms_current.get_positions()[ atomic_numbers[atoms_id]] else: print(atoms_id) atoms_current = atoms[atoms_id] pos_marker = None shift_cell = np.array([0., 0., 0.]) cell = atoms_current.get_cell() if periodic_repetition_str != '(0,1) (0,1) (0,1)' and np.sum( atoms_current.get_pbc()) > 0: x_rep, y_rep, z_rep = periodic_repetition_str.split(' ') x_rep = [int(x) for x in x_rep[1:-1].split(',')] x_multi = x_rep[1] - x_rep[0] y_rep = [int(y) for y in y_rep[1:-1].split(',')] y_multi = y_rep[1] - y_rep[0] z_rep = [int(z) for z in z_rep[1:-1].split(',')] z_multi = z_rep[1] - z_rep[0] #shift_cell = atoms_current.get_center_of_mass() atoms_current = deepcopy(atoms_current) * np.array( [x_multi, y_multi, z_multi]) # shift correctly, we need to correct for the viewers automatic com centering new_positions = np.array([ x + (cell[0] * x_rep[0] + cell[1] * y_rep[0] + cell[2] * z_rep[0]) for x in atoms_current.get_positions() ]) atoms_current.set_positions(new_positions) atoms_current.set_cell(cell) shapes = return_shape_callback(atoms_current, pos_marker, shift_cell=shift_cell) return json.loads( helpers.ase2json(atoms_current)), shapes, atoms_current @app.callback(dash.dependencies.Output('div-3dviewer', 'children'), [ dash.dependencies.Input('graph', 'clickData'), dash.dependencies.Input('periodic_repetition_structure', 'value') ]) def update_3dviewer(callback_hoverdict, periodic_repetition_structure, default=-1): global callback_hoverdict_global run_update = True if periodic_repetition_structure == None: periodic_repetition_structure = '(0,1) (0,1) (0,1)' elif not periodic_repetition_structure.count( '(') == 3 or not periodic_repetition_structure.count(')') == 3: run_update = False if not run_update: raise Exception('no update required') if not callback_hoverdict == None: callback_hoverdict_global = callback_hoverdict if callback_hoverdict_global == []: atoms_id = 0 else: atoms_id = callback_hoverdict_global["points"][0]["pointNumber"] modelData, shapes, atoms_current = return_modelData_atoms( atoms_id, periodic_repetition_str=periodic_repetition_structure) styles = helpers.return_style(atoms_current) view = dash_bio.Molecule3dViewer( id='3d-viewer', styles=styles, shapes=shapes, modelData=modelData) #modelData) #])), return view app.run_server(debug=False, port=9999)
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css'] app = dash.Dash(__name__, external_stylesheets=external_stylesheets) model_data = urlreq.urlopen( 'https://raw.githubusercontent.com/plotly/dash-bio-docs-files/master/mol3d/model_data.js' ).read() styles_data = urlreq.urlopen( 'https://raw.githubusercontent.com/plotly/dash-bio-docs-files/master/mol3d/styles_data.js' ).read() model_data = json.loads(model_data) styles_data = json.loads(styles_data) app.layout = html.Div([ dashbio.Molecule3dViewer(id='my-dashbio-molecule3d', styles=styles_data, modelData=model_data), "Selection data", html.Hr(), html.Div(id='molecule3d-output') ]) @app.callback( dash.dependencies.Output('molecule3d-output', 'children'), [dash.dependencies.Input('my-dashbio-molecule3d', 'selectedAtomIds')]) def show_selected_atoms(atom_ids): if atom_ids is None or len(atom_ids) == 0: return 'No atoms have been selected. Click somewhere on the molecular structure to select an atom.' return [ html.Div([ html.Div('Element: {}'.format(
def layout_descriptors(id): mols_df = db_select_molecules(molecule_ids=[ObjectId(id)]) mol_record = db_connect('molecules').find_one({'_id': ObjectId(id)}) try: rdmol, energies = db_get_rdkit_mol(mol_record) # make alternating single/double bonds for aromatics Chem.SanitizeMol(rdmol) Chem.Kekulize(rdmol, clearAromaticFlags=True) # extract geometry info from the molecule elements, coords, conn, _ = extract_from_rdmol(rdmol) N = len(elements) Nconf = len(coords) if Nconf <= 10: marks = {i: str(i) for i in range(1, Nconf + 1)} else: marks = {i: str(i) for i in range(1, Nconf + 1, int(Nconf / 10))} modelData = { 'atoms': [{ 'name': e, 'element': e, 'positions': c.tolist(), 'serial': i } for i, (e, c) in enumerate(zip(elements, coords[0]))], 'bonds': [{ 'atom1_index': i, 'atom2_index': j, 'bond_order': int(conn[i][j]) } for j in range(N) for i in range(N) if (i < j) and (conn[i][j] > 0)] } stylesData = { str(i): { "color": f"#{jmolcolors.loc[e]}", "visualization_type": "stick" } for i, e in enumerate(elements) } ismol = True except AssertionError: logger.warning("Cannot create rdmol from DB.") ismol = False can = mols_df['can'].iloc[0] desc = descriptors_from_mol_df(mols_df, conf_option='boltzmann').iloc[0] d = desc['descriptors'].to_frame().T df_atom = desc['atom_descriptors'] df_atom.insert(0, 'label', desc['labels']) df_atom.insert(0, 'atom_idx', range(df_atom.shape[0])) trans = desc['transitions'] return html.Div(children=[ dcc.Store(id='store', data={ 'elements': elements, 'coords': coords, 'conn': conn, 'energies': energies }) if ismol else dcc.Store(id='store'), html.Div([ dbc.Label(f"{can}", style={"font-weight": "bold"}, size='lg'), html.Div(children=[ html.P(id='conf_energy', children="", style={ "font-weight": "bold", 'align': 'center' }), dbio.Molecule3dViewer( id='molecule3d', modelData=modelData, styles=stylesData), dcc.Slider(id='conf-slider', min=1, max=Nconf, step=1, value=1, marks=marks) ], style={'width': '500px'}) if ismol else html. Div(children=[html.Br(), html.Img(src=image(can))]), dbc.Table.from_dataframe(d, responsive=True), dbc.Label("Atom-Level Descriptors", style={"font-weight": "bold"}, size='lg'), dbc.Table.from_dataframe(df_atom, responsive=True), dbc.Label("Excited State Transitions", style={'font-weight': 'bold'}, size='lg'), dbc.Table.from_dataframe(trans, responsive=True), ], style={'margin': '10px'}) ])
layout = html.Div([ html.H3('Dash Bio', style=compTitle), html.H3('アライメントチャートと呼ばれるチャート', style={ 'textAlign': 'center', 'margin': '3%' }), dashbio.AlignmentChart(id='my-alignment-viewer', data=data), html.Div(id='alignment-viewer-output'), html.Div([ html.H3('やったった感が得られる3Dチャート4行!', style={ 'textAlign': 'center', 'margin': '3%' }), dashbio.Molecule3dViewer( styles=styles_data, modelData=model_data, selectionType='Chain') ], style={'margin': '10%'}), # TIPS1 html.Div([ html.H3('TIPS 1', style=compTitle), html.Div([ html.H3('Dashに再生ボタンない問題', style={ 'textAlign': 'center', 'margin': '3%' }), html.Div([ daq.LEDDisplay(id='leddisplay', value=0.00000,
# Create the cartoon style from the decoded contents datstyle = sparser.create_style(fname, 'cartoon', 'residue', **{}) fstyle = files_data_style(datstyle) with open(fstyle) as sf: data_style = json.load(sf) pdb = dbc.Card( [ html.H4("Potential allosteric site of IP-10 (CXCL10) oligomer (PDB entry = 1O80).", className="card-title"), #html.H6("a subtitle about pdb file", className="card-subtitle"), html.P( "Our initial network analysis revealed that IP-10/CXCL10 might be a beneficial protein target for reducing cytokine storm in COVID-19 patients if inhibited by a small molecule for example. We have identified a potentially druggable allosteric site for follow-up in silico screening against compound databases (e.g. BindingDB - https://www.bindingdb.org/bind/index.jsp). Please feel free to manipulate the structure to gain more insight. ", className="card-text", ), html.Div( [ dashbio.Molecule3dViewer( id='molecule3d', selectionType='atom', modelData=mdata, styles=data_style, backgroundOpacity='0', atomLabelsShown=False, ) ], style={'width': '100%', 'height': '600px', 'border': 'solid 2px black'} ), ], className="col-lg-6 col-sm-12 offset-md-3 offset-sm-2 float-md-center shadow-lg p-3 mb-5 bg-white rounded", color='dark', outline=True )
div_list1=[html.P(children='''2D Structures of a Specific Molecular Graph''', style={'font-size':'15pt','font-family':'Helvetica','margin-left':'30px'})] div_list1.append(html.Div(children=['Graph ID: ',dcc.Input(id='g-id1',value=1,type='number',style={'border-radius':'5px','width':'40px'}), '----- Graph Label: ', html.Div(id='label2',children='Molecule Label: 1')],style={'margin-left':'60px','textAlign':'center','display':'flex'})); div_list1.append(html.Hr()); data_2d=Get_2Ddata(1); div_list1.append(html.Div([ dashbio.Molecule2dViewer( id='my-dashbio-molecule2d', modelData=data_2d, ), ],style={'margin-left':'150px'})) for i in range(1,16): temp_data=Get_data(i); div_list.append(html.Div(id='view'+str(i),children=[dashbio.Molecule3dViewer(styles=data,modelData=temp_data)])); app.layout = html.Div([html.Div([ html.H1(children='''Data Visualization for Deep Learning Project''', style={'textAlign':'center','color':'#7FDBFF'},id='testt'), html.Div(children=div_list,style={'border':'thin lightgrey solid','margin':'0 auto','width':'800px','border-radius':'5px','background':'#FCFCFC','box-shadow':'rgb(240, 240, 240) 5px 5px 5px 0px'}), html.Div(children=div_list1,style={'border':'thin lightgrey solid','margin':'0 auto','width':'800px','border-radius':'5px','background':'#FCFCFC','box-shadow':'rgb(240, 240, 240) 5px 5px 5px 0px'}) ])], style={'background':'''linear-gradient(rgba(255, 255, 255, 0.6),rgba(255, 255, 255, 0.6)),url("https://raw.githubusercontent.com/plotly/dash-docs/master/images/dash-pattern.png")'''}) call_list=[dash.dependencies.Output(component_id='label1', component_property='children')]; return_list=[str(Graph_Label_list[1])]; for i in range(1,16): call_list.append(dash.dependencies.Output(component_id='view'+str(i), component_property='style')); return_list.append({'display':'none'});
import dash_bio as dashbio model_data = urlreq.urlopen( 'https://raw.githubusercontent.com/plotly/dash-bio-docs-files/master/mol3d/model_data.js' ).read() styles_data = urlreq.urlopen( 'https://raw.githubusercontent.com/plotly/dash-bio-docs-files/master/mol3d/styles_data.js' ).read() model_data = json.loads(model_data) styles_data = json.loads(styles_data) app = dash.Dash(__name__) component = dashbio.Molecule3dViewer(id='molecule3dviewer', styles=styles_data, backgroundOpacity='0', modelData=model_data, selectionType='atom') app.layout = html.Div( [component, html.Div('Selected atom IDs:'), html.Div(id='output')]) @app.callback(dash.dependencies.Output('output', 'children'), [dash.dependencies.Input('molecule3dviewer', 'selectedAtomIds')]) def print_selected(selected): if selected is None or len(selected) == 0: return "No atoms selected." selected = [str(selection) for selection in selected]
def get_tab_layout_visualiser(data, store=True): # STYLE SETTINGS # const_style_dropdown = {'height': '35px', 'width': '100%', 'display': 'inline-block'} const_style_dropdown = dict() markdown_text = """**Green sphere:** Selected atom marker. **Gray wireframe:** SOAP cutoff radius. **Mouse-Navigation:** *Mouse:* Rotate, *Ctrl+Mouse:* Translate, *Shift+Mouse:* Zoom """ layout = html.Div(className='app-body', children=[ # storage of the data in the application dcc.Store(id='app-memory', data=data, storage_type='session') if store else None, # Controls: Dropdown menus, opacity and choice of colourscale html.Div(className="app__controls", children=[ # dropdown menu for the x-axis html.Span(className='app__dropdown', children=["x-axis", html.Br(), dcc.Dropdown(id='dropdown-x-axis', style=const_style_dropdown, options=[], value=0)]), # dropdown menu for the y-axis html.Span(className='app__dropdown', children=["y-axis", html.Br(), dcc.Dropdown(id='dropdown-y-axis', style=const_style_dropdown, options=[], value=0)]), # dropdown menu for the marker size html.Span(className='app__dropdown', children=["marker size", html.Br(), dcc.Dropdown(id='dropdown-marker-size', style=const_style_dropdown, options=[], value=0)]), # dropdown menu for the marker colour html.Span(className='app__dropdown', children=["marker colour", html.Br(), dcc.Dropdown(id='dropdown-marker-colour', style=const_style_dropdown, options=[], value=0)]), # input field for marker opacity html.Span(className='app__dropdown', children=['marker opacity', html.Br(), dcc.Input( id='input-marker-opacity', type='text', placeholder='marker opacity 0.0 - 1.0')]), # input field for colourscale html.Span(className='app__dropdown', children=['colourscale name', html.Br(), dcc.Input( id='input-colourscale', type='text', placeholder='colourscale')]) ]), # Controls: Sliders for colour and size limits html.Div(className='app__controls', children=[ # Slider: marker size limits s html.Span(className='app__slider', children=['marker size range', dcc.RangeSlider(id='slider_marker_size_range', min=1, max=100, step=0.1, value=[5, 50], marks={s: str(s) for s in range(0, 101, 10)}, allowCross=False)]), # New slider for marker size limits html.Span(className='app__slider', children=["marker-size-limits", dcc.RangeSlider( id='slider_marker_size_limits', min=0, max=100, step=0.1, value=[0, 100], marks={p: '{}%'.format(p) for p in range(0, 101, 10)}, allowCross=False, )], ), # Slider: marker colour limits html.Span(className='app__slider', children=["marker colour limits", dcc.RangeSlider(id='slider_marker_color_limits', min=0, max=100, step=0.1, value=[0, 100], marks={p: '{}%'.format(p) for p in range(0, 101, 10)}, allowCross=False, )], ), # two of Br, perhaps we can remove these? html.Br(), html.Br(), ]), # Graph: placeholder, filled on graph intialisation html.Div(className='app__container_scatter', children=[ dcc.Graph(id='graph', figure={'data': [], 'layout': {}})], ), # 3D Viewer # a main Div, with a dcc.Loading compontnt in it for loading of the viewer html.Div( className='app__container_3dmolviewer', style={'height': data['styles']['height_viewer'], 'width_graph': data['styles']['width_viewer']}, children=[ # some info about the viewer dcc.Markdown(markdown_text, className='app__remarks_viewer'), # Input field for the periodic images html.Span(className='app__remarks_viewer', # fixme: missing style children=['Periodic repetition of structure: ', dcc.Input(id='input_periodic_repetition_structure', type='text', placeholder='(0,1) (0,1) (0,1)')]), # loading component for the 3d viewer dcc.Loading( # a div to hold the viewer html.Div(id='div-3dviewer', children=[ # the actual viewer will be initialised here # noinspection PyUnresolvedReferences dash_bio.Molecule3dViewer(id='3d-viewer', styles={}, shapes={}, modelData={}) ]))]) ]) return layout
def upload_data(content, table_ts, stored_data, table_data, selected_columns, dbviewer): """ Uploads the data from an xyz file and store them in the store component. Then set up the dropdowns, the table and the molecule viewer. """ if table_ts is not None: # update stored data from current data in the table df = pd.DataFrame(stored_data) try: table_df = pd.DataFrame(table_data) table_df = table_df.astype({col: np.float for col in table_df if col != "species"}) df.update(table_df) except ValueError: print("No update of data") all_data = df.to_dict("records") else: # Initial set up, read data from upload # read file if content: content_type, content_str = content.split(",") decoded = base64.b64decode(content_str).decode("utf-8") fdata = io.StringIO(decoded) species, coords, atomic_prop = utils.read_xyz(fdata) else: # filename = app.get_asset_url("data/C28-D2.xyz") filename = "assets/data/C28-D2.xyz" with open(filename, "r") as f: species, coords, atomic_prop = utils.read_xyz(f) # comute data df, distances = utils.compute_data(species, coords) if atomic_prop: df_prop = pd.DataFrame(atomic_prop, index=df.index) df = pd.merge(df, df_prop, left_index=True, right_index=True) if "custom" not in df: df["custom"] = 0.0 model_data = utils.get_molecular_data(species, coords) # all data for the store component all_data = df.to_dict("records") # Set the molecule 3D Viewer component dbviewer = dash_bio.Molecule3dViewer( id='molecule-viewer', backgroundColor="#FFFFFF", # backgroundOpacity='0', modelData=model_data, atomLabelsShown=True, selectionType='atom' ) # options for the checklist in order to select the columns of the table selected_columns = ["atom index", "species", "angular defect", "Pyr(A)", "n_neighbors"] # options to select data mapped on atoms options = [{"label": name, "value": name} for name in df if name not in ["atom index", "species"]] # checklist options to select table columns tab_options = [{"label": name, "value": name} for name in df] return all_data, dbviewer, options, tab_options, selected_columns
'applyForce': True, 'circularizeExternal': True, 'avoidOthers': True, 'labelInterval': 5, 'name': 'PDB_01019' } }] model_data = urlreq.urlopen( 'https://raw.githubusercontent.com/plotly/dash-bio-docs-files/' + 'master/mol3d/model_data.js').read() styles_data = urlreq.urlopen( 'https://raw.githubusercontent.com/plotly/dash-bio-docs-files/' + 'master/mol3d/styles_data.js').read() model_data = json.loads(model_data) styles_data = json.loads(styles_data) app.layout = html.Div(children=[ dashbio.AlignmentChart(id='my-dashbio-alignmentchart', data=data), dashbio.FornaContainer(id='my-dashbio-fornacontainer', sequences=sequences), dashbio.Molecule3dViewer(id='my-dashbio-molecule3dviewer', modelData=model_data, styles=styles_data, backgroundOpacity='0') ]) if __name__ == '__main__': app.run_server(debug=True)