{ "cells": [ { "cell_type": "markdown", "id": "1d6b083d-f595-4438-917c-36e2cadc0043", "metadata": {}, "source": [ "# 🧪 Panel Chemistry - Py3DMol Pane\n", "\n", "The Panel Chemistry `py3DMol` allows you to use the powerful [py3Dmol viewer](https://colab.research.google.com/drive/1T2zR59TXyWRcNxRgOAiqVPJWhep83NV_?usp=sharing#scrollTo=3uNCGj3DGx5d) using Python 🐍 and [HoloViz Panel](https://panel.holoviz.org/) ❤️. \n", "\n", "![JSME Editor App](../assets/Py3DMol.gif)\n", "\n", "When using py3DMol please cite\n", "\n", "- Nicholas Rego and David Koes, 3Dmol.js: molecular visualization with WebGL, Bioinformatics (2015) 31 (8): 1322-1324 [doi:10.1093/bioinformatics/btu829](https://academic.oup.com/bioinformatics/article/31/8/1322/213186).\n", " \n", "## Parameters:\n", "\n", "* **``object``** (py3Dmol.view): A `py3Dmol.view` object to display\n", "* **``layout``** (HTML): A Panel HTML pane containing the `html` and `javascript` needed to render the `object`.\n", "\n", "After instantiation of the object you can provide layout options (height, width, sizing_mode etc) to the `layout`. See the [Panel Customization Guide](https://panel.holoviz.org/user_guide/Customization.html).\n", "\n", "## Known Issues\n", "\n", "- You cannot currently display a Py3DMol pane in multiple notebook cells. For this use case just create multiple instances of the Py3DMol pane for now." ] }, { "cell_type": "code", "execution_count": null, "id": "96fe869e-3ebd-4a12-9e7d-b934af3e87bc", "metadata": {}, "outputs": [], "source": [ "import py3Dmol\n", "import panel as pn\n", "\n", "from panel_chemistry.pane import Py3DMol\n", "\n", "pn.extension()" ] }, { "cell_type": "markdown", "id": "79f862a0-beaa-4f0a-8e92-a03c6f8a63af", "metadata": {}, "source": [ "## Basic Example" ] }, { "cell_type": "code", "execution_count": null, "id": "5e7c85a6-aa70-49de-a548-a2f516d7dce5", "metadata": {}, "outputs": [], "source": [ "p = py3Dmol.view(query=\"mmtf:1ycr\")\n", "p.setStyle({\"cartoon\": {\"color\": \"spectrum\"}})\n", "pviewer=Py3DMol(p, height=400, sizing_mode=\"stretch_width\", name=\"Basic\")\n", "pviewer" ] }, { "cell_type": "markdown", "id": "eac14fad-c311-43ed-8806-4ee0d1042963", "metadata": {}, "source": [ "## Grid Example" ] }, { "cell_type": "code", "execution_count": null, "id": "4a71a512-fd82-4018-8302-bde44258c062", "metadata": {}, "outputs": [], "source": [ "gridviewer = py3Dmol.view(query='pdb:1dc9',viewergrid=(2,2),style=[[{'stick':{}},{'cartoon':{'arrows':True, 'tubes':True, 'style':'oval', 'color':'white'}}],\n", " [{'stick':{'colorscheme':'greenCarbon'}},{'cartoon':{'color':'spectrum'}}]])\n", "gridviewer = Py3DMol(gridviewer, height=400, sizing_mode=\"stretch_width\", name=\"Grid\")\n", "gridviewer" ] }, { "cell_type": "markdown", "id": "4ad50a1f-0c74-4de0-b389-ead83e98b172", "metadata": {}, "source": [ "## Interactive Example" ] }, { "cell_type": "code", "execution_count": null, "id": "b4f628bb-9cc9-480f-9bf8-621fbf16a409", "metadata": {}, "outputs": [], "source": [ "xyz = '''4\n", "* (null), Energy -1000.0000000\n", "N 0.000005 0.019779 -0.000003 -0.157114 0.000052 -0.012746\n", "H 0.931955 -0.364989 0.000003 1.507100 -0.601158 -0.004108\n", "H -0.465975 -0.364992 0.807088 0.283368 0.257996 -0.583024\n", "H -0.465979 -0.364991 -0.807088 0.392764 0.342436 0.764260\n", "'''" ] }, { "cell_type": "code", "execution_count": null, "id": "026828fc-d8c9-4a33-9c63-0d72fc982dd8", "metadata": {}, "outputs": [], "source": [ "xyzview = py3Dmol.view()\n", "xyzview.addModel(xyz,'xyz',{'vibrate': {'frames':10,'amplitude':1}})\n", "xyzview.setStyle({'stick':{}})\n", "xyzview.setBackgroundColor('0xeeeeee')\n", "xyzview.animate({'loop': 'backAndForth'})\n", "xyzview.zoomTo()\n", "xyzviewer = Py3DMol(xyzview, height=400, sizing_mode=\"stretch_width\", name=\"Interactive\")\n", "xyzviewer" ] }, { "cell_type": "markdown", "id": "ba4c0a71-aec1-4cbf-9cd2-dba3185445a9", "metadata": {}, "source": [ "You can change the `object` of Py3DMol" ] }, { "cell_type": "code", "execution_count": null, "id": "c3d45854-521c-4ea1-b1c5-8df0a3fc654b", "metadata": {}, "outputs": [], "source": [ "xyzviewer.object = p" ] }, { "cell_type": "markdown", "id": "855de654-ae13-41d5-a749-e25031702ca1", "metadata": {}, "source": [ "... and change it back again" ] }, { "cell_type": "code", "execution_count": null, "id": "e1d8d527-a128-47fb-946e-89a012850e7e", "metadata": {}, "outputs": [], "source": [ "xyzviewer.object = xyzview" ] }, { "cell_type": "markdown", "id": "430fbbd1-7e41-48ae-ad51-afa8af458918", "metadata": {}, "source": [ "we can change the background color" ] }, { "cell_type": "code", "execution_count": null, "id": "9d5494c5-c8ba-41c2-a54b-64596333b5e1", "metadata": {}, "outputs": [], "source": [ "def set_background(color='0xeeeeee'):\n", " xyzview.setBackgroundColor(color)\n", " xyzviewer.param.trigger(\"object\")\n", "set_background(\"#e6f6ff\")" ] }, { "cell_type": "markdown", "id": "2d77e59d-250f-41da-bfa3-16f2f63e0e72", "metadata": {}, "source": [ "... and use a `ColorPicker` widget to speed up your workflow" ] }, { "cell_type": "code", "execution_count": null, "id": "adf53821-5d9f-48f1-83e3-91ff77a4930c", "metadata": {}, "outputs": [], "source": [ "background = pn.widgets.ColorPicker(value=\"#e6f6ff\", name=\"Background\")\n", "pn.bind(set_background, color=background, watch=True)\n", "background" ] }, { "cell_type": "markdown", "id": "9eecb587-00cd-4345-b849-d3d5b03f04a7", "metadata": {}, "source": [ "We can also change the `style`" ] }, { "cell_type": "code", "execution_count": null, "id": "dfe11bc0-6c87-4daf-9f85-118490b75cb5", "metadata": {}, "outputs": [], "source": [ "def set_style(style=\"stick\"):\n", " xyzview.setStyle({style: {}})\n", " xyzview.zoomTo()\n", " xyzviewer.param.trigger(\"object\")\n", " \n", "set_style(\"sphere\")" ] }, { "cell_type": "markdown", "id": "6f9dd187-6eed-40c6-aad9-7255e0b0bb8c", "metadata": {}, "source": [ "... and use a `RadioButtonGroup` to speed up your workflow" ] }, { "cell_type": "code", "execution_count": null, "id": "4cd8f969-7058-40a3-a51e-e5163e1e479c", "metadata": {}, "outputs": [], "source": [ "style=pn.widgets.RadioButtonGroup(value=\"sphere\", options=[\"line\", \"cross\", \"stick\", \"sphere\"], name=\"Style\", button_type=\"success\")\n", "set_style=pn.bind(set_style, style=style, watch=True)\n", "style" ] }, { "cell_type": "markdown", "id": "0423f09e-f638-4c93-bcb5-04b5ddbe3cea", "metadata": {}, "source": [ "## Wrap it up as an Application" ] }, { "cell_type": "code", "execution_count": null, "id": "a90a2375-8c6f-4b69-8c97-23203355ab01", "metadata": {}, "outputs": [], "source": [ "accent = \"#0072B5\"" ] }, { "cell_type": "code", "execution_count": null, "id": "0059c7e5-e61d-4b5f-9feb-70e038cb882f", "metadata": {}, "outputs": [], "source": [ "pn.template.FastListTemplate(\n", " site=\"Panel Chemistry\", site_url=\"./\",\n", " title=\"Py3DMol Pane\", \n", " sidebar=[background, style],\n", " main=[pn.Tabs(xyzviewer, gridviewer, pviewer)],\n", " header_background=accent, accent_base_color=accent\n", ").servable();" ] }, { "cell_type": "markdown", "id": "0b395c85-793e-4f12-ab68-0afa97c7515e", "metadata": {}, "source": [ "Serve the app via `panel serve Py3DMol.ipynb` and check it out at http://localhost:5006/Py3DMol.\n", "\n", "If you add the flag `--autoreload` you will get automatic reloading when ever you save the file.\n", "\n", "You can also use the [Panel Jupyter Preview](https://blog.holoviz.org/panel_0.12.0.html#JupyterLab-previews) to serve the app in a seperate window in Jupyter Lab." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.4" } }, "nbformat": 4, "nbformat_minor": 5 }