# dash_bioMolecule3dViewer Examples and Reference

see Molecule3dViewer in action.

## Molecule3dViewer

An example of a default Molecule3dViewer component without any extra properties.

Selection data

    library(dash)
    library(dashHtmlComponents)
    library(dashCoreComponents)
    library(dashBio)
    library(jsonlite)

    model_data <- read_json("https://git.io/mol3d-model_data.js")
    styles_data <- read_json("https://git.io/mol3d-styles_data.js")

    app <- Dash$new()

    app$layout(
        htmlDiv(
            list(
                dashbioMolecule3dViewer(
                    id = 'dashbio-molecule3d-default',
                    styles = styles_data,
                    modelData = model_data,
                    selectionType = 'Chain',
                ),
            "Selection data",
            htmlHr(),
            htmlDiv(id = 'default-molecule3d-output')
            )
        )
    )

    app$callback(
        output = list(id = 'default-molecule3d-output', property = 'children'),
        params = list(input(id = 'dashbio-molecule3d-default', property = 'selectedAtomIds')),

        show_selected_atoms <- function(atom_ids) {
            if (is.null(atom_ids[[1]]) | length(atom_ids) < 1 ) {
                return("No atom has been selected. Click somewhere on the molecular structure to select an atom.")
            }
            else {
                return(sprintf("Element or atom ID: %s", as.character(paste(unlist(atom_ids$name), collapse=' - '))))
            }
        }
    )

    app$run_server()

## Customization

### Zoom Factor

The current stage of the molecule viewer can be zoomed by a constant factor with the zoom prop. This maintains the rotation and orientation of the stage while zooming, as well as any selections or property changes from other callbacks.

It is important to note that the `zoom` animation can conflict with the `zoomTo` animation if both props are set. In this case, it is recommended to set animationDuration to values that would not overlap, or use `fixedPath` to prioritize the animation which occurs.

> This example has not been ported to R yet - showing the Python version instead.

> Visit the old docs site for R at: https://community.plotly.com/c/dash/r/21

0.4 0.8 1.2 1.6

    import json
    import urllib.request as urlreq
    from dash import Dash, html, dcc, Input, Output, callback
    import dash_bio as dashbio

    app = Dash()

    model_data = urlreq.urlopen(
        'https://git.io/mol3d-model_data.js'
    ).read().decode('utf-8')

    styles_data = urlreq.urlopen(
        'https://git.io/mol3d-styles_data.js'
    ).read().decode('utf-8')

    model_data = json.loads(model_data)
    styles_data = json.loads(styles_data)

    app.layout = html.Div(
        [
            dashbio.Molecule3dViewer(
                id="zoomfactor-molecule3d", styles=styles_data, modelData=model_data
            ),
            dcc.Slider(
                id="zoomfactor-slider",
                min=0.4,
                max=2.0,
                step=None,
                marks={0.4: "0.4", 0.8: "0.8", 1.2: "1.2", 1.6: "1.6", 2.0: "2.0"},
                value=0.8,
            ),
        ]
    )

    @callback(
        Output("zoomfactor-molecule3d", "zoom"),
        Input("zoomfactor-slider", "value"),
        prevent_initial_call=True,
    )
    def zoom(value):
        return {"factor": value, "animationDuration": 1000, "fixedPath": False}

    if __name__ == "__main__":
        app.run(debug=True)

### Zooming to Specific Residues

We can zoom into specific residues and chains on the molecule by setting the `zoomTo` prop. An optional `animationDuration` denotes the duration of the zoom animation (in milliseconds),

The `chain` key indicates the protein chain identifier from the molecule's model data, and `resi` is the internal integer index value on the chain for the residue of interest.

In the example below, select the rows on the table to zoom into and label the chosen residue.

> This example has not been ported to R yet - showing the Python version instead.

> Visit the old docs site for R at: https://community.plotly.com/c/dash/r/21

| serial | name | elem | positions | mass_magnitude | residue_index | residue_name | chain
--- | --- | --- | --- | --- | --- | --- | --- | ---
| 0 | N | N | -34.168, 48.168, -15.656 | 14.0067 | 0 | MET | A
| 8 | N | N | -33.69, 45.612, -17.978 | 14.0067 | 1 | ILE | A
| 16 | N | N | -35.937, 43.048, -18.803 | 14.0067 | 2 | LEU | A
| 24 | N | N | -36.966, 41.12, -20.708 | 14.0067 | 3 | ASP | A
| 32 | N | N | -37.233, 40.312, -24.274 | 14.0067 | 4 | THR | A
| 47 | N | N | -41.013, 40.049, -30.364 | 14.0067 | 6 | TYR | A
| 74 | N | N | -47.009, 44.437, -36.893 | 14.0067 | 9 | GLU | A
| 83 | N | N | -49.04, 45.578, -39.367 | 14.0067 | 10 | ASN | A
| 91 | N | N | -47.665, 43.888, -41.244 | 14.0067 | 11 | GLY | A
| 95 | N | N | -45.04, 44.361, -40.649 | 14.0067 | 12 | LYS | A

1
/
3

    from dash import Dash, html, dash_table, Input, Output, callback
    import dash_bio as dashbio
    from dash_bio.utils import PdbParser, create_mol3d_style
    import pandas as pd

    app = Dash()

    parser = PdbParser('https://git.io/4K8X.pdb')

    data = parser.mol3d_data()
    styles = create_mol3d_style(
        data['atoms'], visualization_type='cartoon', color_element='residue'
    )

    df = pd.DataFrame(data["atoms"])
    df = df.drop_duplicates(subset=['residue_name'])
    df['positions'] = df['positions'].apply(lambda x: ', '.join(map(str, x)))

    app.layout = html.Div(
        [
            dash_table.DataTable(
                id="zooming-specific-residue-table",
                columns=[{"name": i, "id": i} for i in df.columns],
                data=df.to_dict("records"),
                row_selectable="single",
                page_size=10,
            ),
            dashbio.Molecule3dViewer(
                id="zooming-specific-molecule3d-zoomto",
                modelData=data,
                styles=styles
            ),
        ]
    )

    @callback(
        Output("zooming-specific-molecule3d-zoomto", "zoomTo"),
        Output("zooming-specific-molecule3d-zoomto", "labels"),
        Input("zooming-specific-residue-table", "selected_rows"),
        prevent_initial_call=True
    )
    def residue(selected_row):
        row = df.iloc[selected_row]
        row['positions'] = row['positions'].apply(lambda x: [float(x) for x in x.split(',')])
        return [
            {
                "sel": {"chain": row["chain"], "resi": row["residue_index"]},
                "animationDuration": 1500,
                "fixedPath": True,
            },
            [
                {
                    "text": "Residue Name: {}".format(row["residue_name"].values[0]),
                    "position": {
                        "x": row["positions"].values[0][0],
                        "y": row["positions"].values[0][1],
                        "z": row["positions"].values[0][2],
                    },
                }
            ],
        ]

    if __name__ == "__main__":
        app.run(debug=True)

### Selection Type

Choose what gets highlighted with the same color upon selection.

    library(dash)
    library(dashHtmlComponents)
    library(dashCoreComponents)
    library(dashBio)
    library(jsonlite)

    model_data <- read_json("https://git.io/mol3d-model_data.js")
    styles_data <- read_json("https://git.io/mol3d-styles_data.js")

    app <- Dash$new()

    app$layout(
        dashbioMolecule3dViewer(
            id = 'my-dashbio-molecule3d',
            styles = styles_data,
            modelData = model_data,
            selectionType = 'Chain'
        )
    )

    app$run_server()

### Background Color/Opacity

Change the background color and opacity of the canvas on which Mol3D is rendered.

    library(dash)
    library(dashHtmlComponents)
    library(dashCoreComponents)
    library(dashBio)
    library(jsonlite)

    model_data <- read_json("https://git.io/mol3d-model_data.js")
    styles_data <- read_json("https://git.io/mol3d-styles_data.js")

    app <- Dash$new()

    app$layout(
        dashbioMolecule3dViewer(
            id = 'my-dashbio-molecule3d',
            styles = styles_data,
            modelData = model_data,
            selectionType = 'Chain',
            backgroundColor='#FF0000',
            backgroundOpacity=0.2
        )
    )

    app$run_server()

### Labels

Add labels corresponding to the atom of the molecule. Label styles can be set with additional parameters. For styling keys, see.

> This example has not been ported to R yet - showing the Python version instead.

> Visit the old docs site for R at: https://community.plotly.com/c/dash/r/21

    import dash_bio as dashbio
    from dash_bio.utils import PdbParser, create_mol3d_style

    parser = PdbParser('https://git.io/4K8X.pdb')

    data = parser.mol3d_data()
    styles = create_mol3d_style(
        data['atoms'], visualization_type='cartoon', color_element='residue'
    )

    dashbio.Molecule3dViewer(
        modelData=data,
        styles=styles,
        labels=[
            {'text': 'Residue Name: GLY1', 'fontColor': 'red', 'font': 'Courier New, monospace'},
            {'text': 'Residue Chain: A', 'position': {'x': 15.407, 'y': -8.432, 'z': 6.573}}
        ],
    )

### Shapes

Add predefined renderable shapes to the molecule. Supported shape types are Arrow, Sphere, and Cylinder.

> This example has not been ported to R yet - showing the Python version instead.

> Visit the old docs site for R at: https://community.plotly.com/c/dash/r/21

    import dash_bio as dashbio
    from dash_bio.utils import PdbParser, create_mol3d_style

    parser = PdbParser('https://git.io/4K8X.pdb')

    data = parser.mol3d_data()
    styles = create_mol3d_style(
        data['atoms'], visualization_type='cartoon', color_element='residue'
    )

    dashbio.Molecule3dViewer(
        modelData=data,
        styles=styles,
        shapes=[
            {
                'type': 'Sphere',
                'center': {'x': 0, 'y': 0, 'z': 0},
                'radius': 3.0,
                'color': 'blue',
                'opacity': 1
            },
            {
                'type': 'Arrow',
                'start': {'x': 40, 'y': 20.0, 'z': 0.0},
                'end': {'x': 20.0, 'y': 10.0, 'z': 0.0},
                'radius': 1.0,
                'radiusRadio': 0.5,
                'mid': 1.0,
                'color': 'red',
                'opacity': 1
            },
            {
                'type': 'Cylinder',
                'start': {'x': 10.0, 'y': -30.0, 'z': 0.0},
                'end': {'x': 20.0, 'y': -50.0, 'z': 0.0},
                'radius': 1.0,
                'fromCap': 1,
                'toCap': 2,
                'color': 'green',
                'opacity': 1
            }
        ],
    )

### Isosurfaces

Render a 3D isosurface. Volumetric orbital data must be provided in the `cube` file format.

> This example has not been ported to R yet - showing the Python version instead.

> Visit the old docs site for R at: https://community.plotly.com/c/dash/r/21

    import urllib.request as urlreq

    import dash_bio as dashbio
    from dash_bio.utils import PdbParser, create_mol3d_style

    parser = PdbParser('https://git.io/4K8X.pdb')

    data = parser.mol3d_data()
    styles = create_mol3d_style(
        data['atoms'], visualization_type='cartoon', color_element='residue'
    )

    cube_data = urlreq.urlopen(
        'https://git.io/benzene-homo.cube'
    ).read().decode('utf-8')

    dashbio.Molecule3dViewer(
        modelData=data,
        styles=styles,
        selectionType='atom',
        orbital={
            'cube_file': cube_data,
            'iso_val': 0.1,
            'opacity': 1.0,
            'positiveVolumetricColor': 'red',
            'negativeVolumetricColor': 'blue',
        }
    )

## Molecule3dViewer Properties

> Our recommended IDE for writing Dash apps is Dash Enterprise's Data Science Workspaces, which has typeahead support for Dash Component Properties. Find out if your company is using Dash Enterprise.

`id` (character; optional): The ID used to identify this component in callbacks.

`selectionType` (a value equal to: 'atom', 'residue' or 'chain'; default `'atom'`): The selection type - may be atom, residue or chain.

`backgroundColor` (character; default `'#FFFFFF'`): Property to change the background color of the molecule viewer.

`backgroundOpacity` (numeric; default `0`): Property to change the background opacity - ranges from 0 to 1.

`styles` (list where each item is a named list; optional): Property that can be used to change the representation of the molecule. Options include sticks, cartoon and sphere.

`styles` is a list where each item is a named list with keys:

- `color` (character; optional)

- `visualization_type` (a value equal to: 'cartoon', 'sphere' or 'stick'; optional)

`modelData` (named list; optional): The data that will be used to display the molecule in 3D The data will be in JSON format and should have two main dictionaries - atoms, bonds.

`modelData` is a named list with keys:

- `atoms` (unnamed list; optional)

- `bonds` (unnamed list; optional)

`atomLabelsShown` (logical; optional): Property to either show or hide labels.

`selectedAtomIds` (unnamed list; optional): Property that stores a list of all selected atoms.

`labels` (unnamed list of named lists; optional): Labels corresponding to the atoms of the molecule. Each label has a `text` field, a string containing the label content, and can have many other styling fields as described in https://3dmol.csb.pitt.edu/doc/types.html#LabelSpec.

`orbital` (named list; optional): Add an isosurface from volumetric data provided in the `cube_file`.

`orbital` is a named list with keys:

- `cube_file` (character; optional): The filepath containing raw volumetric data for vertex coloring.

- `iso_val` (numeric; optional): The isovalue to draw the surface at.

- `negativeVolumetricColor` (character; optional): Color for the negative value of the isosurface orbital.

- `opacity` (numeric; optional): Transparency of the surface, between 0 and 1.

- `positiveVolumetricColor` (character; optional): Color for the positive value of the isosurface orbital.

`zoom` (named list; default `{ factor: 0.8, animationDuration: 0, fixedPath: FALSE,}`): Zoom the current view by a constant factor, with optional parameters to modify the duration and motion of the zoom animation.

`zoom` is a named list with keys:

- `animationDuration` (numeric; optional): An optional parameter that denotes the duration of a zoom animation, in milliseconds.

- `factor` (numeric; optional): Magnification factor. Values greater than 1 will zoom, in, less than one will zoom out. Default 2.

- `fixedPath` (logical; optional): If TRUE, animation is constrained to requested motion, overriding updates that happen during the animation.

`zoomTo` (named list; default `{ sel: {}, animationDuration: 0, fixedPath: FALSE,}`): Zoom to center of atom selection.

`zoomTo` is a named list with keys:

- `animationDuration` (numeric; optional): An optional parameter that denotes the duration of a zoom animation , in milliseconds.

- `fixedPath` (logical; optional): If TRUE, animation is constrained to requested motion, overriding updates that happen during the animation.

- `sel` (named list; optional): Selection specification specifying model and atom properties to select. Default: all atoms in viewer.

  `sel` is a named list with keys:

  - `chain` (character; optional): Chain that the residue is located on.

  - `resi` (numeric; optional): The index value used to identify the residue; residues are numbered sequentially starting from 1.

`shapes` (unnamed list of named lists; optional): Add a predefined renderable shape objects to the molecule. Valid shape types are Arrow, Sphere, and Cylinder.

`height` (numeric; optional): The height (in px) of the container.

`width` (numeric; optional): The width (in px) of the container.

`style` (named list; default `{ height: 500, width: 500,}`): Generic style overrides on the plot div.

`onRenderNewData` (optional): Callback to re-render molecule viewer when modelData is changed.

`onChangeSelection` (optional): Callback to change append selectedAtomIds when a selection is made.

`loading_state` (named list; optional): Object that holds the loading state object coming from dash-renderer.

`loading_state` is a named list with keys:

- `component_name` (character; optional): Holds the name of the component that is loading.

- `is_loading` (logical; optional): Determines if the component is loading or not.

- `prop_name` (character; optional): Holds which property is loading.

## Example Data

- https://github.com/plotly/datasets/blob/master/Dash_Bio/Molecular/mol3d/model_data.js
- Computational predictions of protein structures associated with COVID-19
- - RCSB Protein Data Bank