Creating your own visualizations#
This tutorial describes how to build custom visualizations
(BaseVisualizations
) in OCE.
We have a unique way of building visualizations in OCE to make them interactive, shareable, and customizable.
The BaseVisualization class#
Basic flow#
Fundamentally BaseVisualization
s are rendered via render_X()
(the function render_ipynb()
returns an output renderable in Jupyter
notebooks and the function render_data_url()
returns a dataURL which
can be pasted in any web browser and rendered).
Each BaseVisualization
is drawn onto a blank div via a JavaScript
template defined by the file specified by the property JS_NAME
. The
render_X()
functions compile the HTML/JavaScript code and populates
the visualization tempalte with the visualization data returned by
get_data()
. save_html
saves the visulalization to a standalone
HTML file.
Notes on use#
Visualizations often require external JavaScript packages to load this
can be specified in self.packages
and a dictionary of such available
packages is in package_urls
.
from olorenchemengine import BaseVisualization, log_arguments
class CustomVis(BaseVisualization):
package_urls = {...}
@log_arguments
def __init__(self, log=True, **kwargs):
self.packages = []
def get_data() -> dict:
"""Get data for visualization in JSON-like dictionary.
"""
return {}
@property
def JS_NAME(self) -> str:
pass
def render(self, data: dict = None, print_html_js=False) -> str:
pass
def save_html(self, path):
pass
def render_ipynb(self, data: dict = None, print_html_js=False) -> str:
pass
def render_data_url(self, data: dict = None, print_html_js=False) -> str:
pass
Notes on attributes class#
You’ll notice two methods in the visualizations, get_attributes()
and from_attributes
. These two methods are used to systematize the
arguments used for visualizations, especially the aesthetic and
BaseClass
subclasses. These attributes are optional, but highly
reccomended for contributed code.
@staticmethod
def get_attributes() -> list:
pass
@classmethod
def from_attributes(cls, attributes: dict) -> "BaseVisualization":
pass
Creating by example#
We will go through an example chemical space plot to show the components of a visualization. We’ll do two run-throughs. The first will show the basic funtional components of the Python class. The second will show the integration with JavaScript.
First run-through#
# This is what the visualization looks like
from olorenchemengine import ChemicalSpacePlot, BACEDataset, MorganVecRepresentation
vis = ChemicalSpacePlot(BACEDataset(), MorganVecRepresentation())
vis.render_ipynb()
Second run-through#
First we’ll show the data that is passed to the HTML/JavaScript created
by get_data()
and then we will show the final combined
HTML/JavaScript + data file.
# This is what the visualization data looks like
vis.get_data()
{'title': 'Chemical Space Plot',
'xaxis_title': 'Component 1',
'yaxis_title': 'Component 2',
'hover_size': 0.4,
'xaxis_type': 'linear',
'yaxis_type': 'linear',
'width': 800,
'height': 600,
'opacity': 1,
'X': [43.61760330200195,
-17.472150802612305,
41.86582946777344,
158.97496032714844,
-24.860200881958008,
-2.232616424560547,
-35.85402297973633,
-67.47518157958984,
55.304420471191406,
-13.724129676818848,
-3.4850451946258545,
-134.3723602294922,
-62.69178771972656,
30.23807716369629,
-5.901937961578369,
10.940505981445312,
-4.623172283172607,
-43.74485778808594,
8.369648933410645,
68.97262573242188,
-22.280351638793945,
-30.012405395507812,
75.25151062011719,
64.52973937988281,
-3.1073720455169678,
-26.3098087310791,
-29.127517700195312,
14.045056343078613,
27.511388778686523,
62.6290168762207,
46.29264831542969,
18.152881622314453,
49.81310272216797,
-81.98030853271484,
41.48120880126953,
89.24085998535156,
27.849729537963867,
-41.686649322509766,
26.67981719970703,
-6.256188869476318,
-26.8016300201416,
8.647194862365723,
-49.416343688964844,
-42.954734802246094,
48.0875129699707,
-25.647356033325195,
23.574270248413086,
-62.410926818847656,
12.529644966125488],
'Y': [-37.546878814697266,
-26.210065841674805,
-12.783864974975586,
27.13193702697754,
87.86702728271484,
-81.90585327148438,
-47.80723571777344,
36.506431579589844,
-61.465553283691406,
-56.813961029052734,
-39.14337921142578,
76.40354919433594,
-47.68071746826172,
6.304887294769287,
61.944801330566406,
44.215999603271484,
-10.914501190185547,
59.72188949584961,
-62.289512634277344,
21.70496940612793,
30.97284507751465,
-73.79450225830078,
-1.874199628829956,
44.48176956176758,
31.48701286315918,
50.19774627685547,
149.90878295898438,
-6.158529281616211,
32.54773712158203,
-22.430017471313477,
33.658206939697266,
67.7158432006836,
6.881969451904297,
1.560334324836731,
59.63355255126953,
-42.17106246948242,
-72.33515930175781,
-26.811941146850586,
-24.993431091308594,
10.065010070800781,
-9.101613998413086,
-25.244958877563477,
1.6200640201568604,
22.73969841003418,
-87.27729034423828,
9.062121391296387,
-48.46100997924805,
-18.139448165893555,
14.488275527954102],
'SMILES': ['CC(C)CC(c1nnnn1C)N(Cc1ccccc1Cl)c1ccc(C#N)c(Cl)c1',
'Cc1c(NS(C)(=O)=O)cccc1N(Cc1ccccc1)Cc1ccc(Oc2ccc(OCC(=O)O)cc2)cc1',
'C=C(C)[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(SC)cc3)OC[C@@]21C',
'CC(C)N1C(=O)OC(C)(C)c2cc(Nc3ccc(Br)cc3)ccc21',
'CS(=O)(=O)Nc1ccc2c(c1)C(c1ccccc1)Oc1cccc(OC(F)F)c1-2',
'CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)CCC(=O)O)cc3)C[C@@]21C',
'CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(NC)cc3)C[C@@]21C',
'CCn1nnnc1C(C)N(Cc1ccccc1Cl)c1ccc(C#N)c(Cl)c1',
'CC1(C)OC(=O)Nc2ccc(-c3ccc(F)c(C#N)c3)cc21',
'CN1C(=O)OC(C)(C)c2cc(Nc3cccc(Cl)c3Cl)ccc21',
'CCOc1cccc2c1-c1ccc(NS(C)(=O)=O)cc1C(c1ccccc1)O2',
'CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)CCCCCC)cc3)C[C@@]21C',
'Cn1nnnc1CN(Cc1ccccc1Cl)c1ccc(C#N)c(Cl)c1',
'C=C1C=C(C)CC(C)(C)C1Cc1ccc([N+](=O)[O-])cc1',
'CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)C)cc3)C[C@@]21C',
'CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)C)cc3)C[C@@]21C',
'CC1(C)OC(=O)N(Cc2ccccc2)c2ccc(Nc3ccc(Br)cc3)cc21',
'C[C@@H]1C[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(-c4ccccn4)cc3)C[C@]2(C)[C@H]1C(=O)C1CC1',
'CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)C(=O)NCCCCCC(=O)N[C@@H](CC(C)C)C(=O)OC(C)(C)C)cc3)C[C@@]21C',
'CN(C)c1ccc([C@H]2OC[C@]3(C)[C@@H](O)CC[C@H]3[C@@H]3CCC4=CC(=O)CCC4=C32)cc1',
'CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)CCC(=O)Nc4ccc(C(N)=O)c(O)c4)cc3)C[C@@]21C',
'CC1=CC(C)(C)Nc2ccc3c(c21)COc1c(Cl)cccc1-3',
'C=C1CCO[C@]12CC[C@H]1[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)C)cc3)OC[C@@]12C',
'CC(c1nnnn1C(C)C)N(Cc1ccccc1Cl)c1ccc(C#N)c(Cl)c1',
'C=C1C(C)=CCC(C)(C)[C@@H]1Cc1cc(OC)c(Br)cc1OC(C)=O',
'CC1=CC(C)(C)Nc2ccc3c(c21)/C(=C/C=O)Oc1ccc(F)cc1-3',
'C=C1C=C(C)CC(C)(C)C1Sc1ccc([N+](=O)[O-])cc1',
'CCCCn1c2ccccc2c2ccc3c(c21)C(C)=CC(C)(C)N3',
'CC(C)CC(c1nnnn1C)N(CC(C)C)c1ccc(C#N)c(Cl)c1',
'C=C1CCCC(C)(C)C1Cc1cc(OC)c(Br)cc1O',
'COc1ccc(-c2ccc([C@H]3C[C@]4(C)[C@@H](C(=O)C5CC5)CC[C@H]4[C@@H]4CCC5=CC(=O)CCC5=C43)cc2)cn1',
'CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)CCCCCC=O)cc3)C[C@@]21C',
'CCC1(CC)OC(=O)N(C)c2ccc(Nc3cccc(Cl)c3)cc21',
'CN(C)c1ccc([C@H]2C[C@]3(C)[C@@H](CC[C@]3(O)CCCO)[C@@H]3CCC4=CC(=O)CCC4=C32)cc1',
'COc1ccccc1-c1ccc2c(c1)C(C(C)OCCc1cccc(Cl)c1)=CC(C)(C)N2',
'CC1(C)[C@H](O)CC[C@]2(C)[C@@]3(C)c4[nH]c5ccccc5c4C[C@@H]3CC[C@@]12O',
'CC(c1cn(C)nn1)N(Cc1ccccc1Cl)c1ccc(C#N)c(Cl)c1',
'CC1(C)OC(C(C)(C)C)Nc2ccc(-c3cc(F)cc(C#N)c3)cc21',
'CC1=CC(C)(C)Nc2cc3oc4ccccc4c3cc21',
'O=[N+]([O-])c1cccc(-c2ccc3nc(S)n(Cc4ccccc4)c3c2)c1',
'O=C(c1ccc([N+](=O)[O-])cc1)N1CCCC(c2ccc(Cl)c(Cl)c2)=N1',
'CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)C(=O)NCCCC)cc3)C[C@@]21C',
'C=C1C(C)=CCC(C)(C)[C@@H]1Cc1cc(OC)c(Br)cc1OC(C)=O',
'CN(C)c1ccc([C@H]2C[C@]3(C)[C@@H](CC[C@]3(O)CCCO)[C@@H]3CCC4=CC(=O)CCC4=C32)cc1',
'CC1=CC(C)(C)Nc2ccc(-c3ccsc3C#N)cc21',
'CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)CCCCCCCC(=O)OC)cc3)C[C@@]21C',
'CCC1(CC)OC(=O)N(C)c2ccc(Nc3cccc(Cl)c3Cl)cc21',
'CC1(C)C(=O)Nc2ccc(-c3cc(F)cc(Cl)c3)cc21',
'C[C@@H]1c2c(ccc3c2[C@H](c2ccc(Cl)cc2)Oc2ccccc2-3)NC(C)(C)[C@H]1O'],
'colorscale': 'Portland'}
This is what the combined vis HTML/JavaScript/Data looks like Notice the first section has a header, then package imports, then a div with id ‘basevis-entry’ which is where the visualization is rendered. The div has the tag data-visdata which has the JSON-ified data returned by get_data(). Then the visualization is rendered with Plotly with the compounds rendered on hover with smilesDrawer.
Note that the bulk of the visualization is performed in the JavaScript
file pointed to by JS_NAME
and the bulk of the processing is done in
Python and returned by get_data. As a general principle, time-intensive
procedures should be performed in the __init__()
of the
visualization with less time-intensive procedures like data filtering
performed in get_data()
After the printed HTML/JavaScript is the dataURL which can be copy pasted without the quotation marks to be rendered in any browser.
vis.render_data_url(print_html_js=True)
<!DOCTYPE html>
<head>
<meta charset="utf-8">
</head>
<html style="height: 100%;">
<!-- Load packages -->
<script src="https://cdn.plot.ly/plotly-2.12.1.min.js"></script><script src="https://unpkg.com/smiles-drawer@1.0.10/dist/smiles-drawer.min.js"></script>
<body style="background-color:#FFFFFF; height: 100%;">
<!-- Create a div where the graph will take place -->
<div id="basevis-entry" data-visdata="{"title": "Chemical Space Plot", "xaxis_title": "Component 1", "yaxis_title": "Component 2", "hover_size": 0.4, "xaxis_type": "linear", "yaxis_type": "linear", "width": 800, "height": 600, "opacity": 1, "X": [43.61760330200195, -17.472150802612305, 41.86582946777344, 158.97496032714844, -24.860200881958008, -2.232616424560547, -35.85402297973633, -67.47518157958984, 55.304420471191406, -13.724129676818848, -3.4850451946258545, -134.3723602294922, -62.69178771972656, 30.23807716369629, -5.901937961578369, 10.940505981445312, -4.623172283172607, -43.74485778808594, 8.369648933410645, 68.97262573242188, -22.280351638793945, -30.012405395507812, 75.25151062011719, 64.52973937988281, -3.1073720455169678, -26.3098087310791, -29.127517700195312, 14.045056343078613, 27.511388778686523, 62.6290168762207, 46.29264831542969, 18.152881622314453, 49.81310272216797, -81.98030853271484, 41.48120880126953, 89.24085998535156, 27.849729537963867, -41.686649322509766, 26.67981719970703, -6.256188869476318, -26.8016300201416, 8.647194862365723, -49.416343688964844, -42.954734802246094, 48.0875129699707, -25.647356033325195, 23.574270248413086, -62.410926818847656, 12.529644966125488], "Y": [-37.546878814697266, -26.210065841674805, -12.783864974975586, 27.13193702697754, 87.86702728271484, -81.90585327148438, -47.80723571777344, 36.506431579589844, -61.465553283691406, -56.813961029052734, -39.14337921142578, 76.40354919433594, -47.68071746826172, 6.304887294769287, 61.944801330566406, 44.215999603271484, -10.914501190185547, 59.72188949584961, -62.289512634277344, 21.70496940612793, 30.97284507751465, -73.79450225830078, -1.874199628829956, 44.48176956176758, 31.48701286315918, 50.19774627685547, 149.90878295898438, -6.158529281616211, 32.54773712158203, -22.430017471313477, 33.658206939697266, 67.7158432006836, 6.881969451904297, 1.560334324836731, 59.63355255126953, -42.17106246948242, -72.33515930175781, -26.811941146850586, -24.993431091308594, 10.065010070800781, -9.101613998413086, -25.244958877563477, 1.6200640201568604, 22.73969841003418, -87.27729034423828, 9.062121391296387, -48.46100997924805, -18.139448165893555, 14.488275527954102], "SMILES": ["CC(C)CC(c1nnnn1C)N(Cc1ccccc1Cl)c1ccc(C#N)c(Cl)c1", "Cc1c(NS(C)(=O)=O)cccc1N(Cc1ccccc1)Cc1ccc(Oc2ccc(OCC(=O)O)cc2)cc1", "C=C(C)[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(SC)cc3)OC[C@@]21C", "CC(C)N1C(=O)OC(C)(C)c2cc(Nc3ccc(Br)cc3)ccc21", "CS(=O)(=O)Nc1ccc2c(c1)C(c1ccccc1)Oc1cccc(OC(F)F)c1-2", "CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)CCC(=O)O)cc3)C[C@@]21C", "CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(NC)cc3)C[C@@]21C", "CCn1nnnc1C(C)N(Cc1ccccc1Cl)c1ccc(C#N)c(Cl)c1", "CC1(C)OC(=O)Nc2ccc(-c3ccc(F)c(C#N)c3)cc21", "CN1C(=O)OC(C)(C)c2cc(Nc3cccc(Cl)c3Cl)ccc21", "CCOc1cccc2c1-c1ccc(NS(C)(=O)=O)cc1C(c1ccccc1)O2", "CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)CCCCCC)cc3)C[C@@]21C", "Cn1nnnc1CN(Cc1ccccc1Cl)c1ccc(C#N)c(Cl)c1", "C=C1C=C(C)CC(C)(C)C1Cc1ccc([N+](=O)[O-])cc1", "CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)C)cc3)C[C@@]21C", "CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)C)cc3)C[C@@]21C", "CC1(C)OC(=O)N(Cc2ccccc2)c2ccc(Nc3ccc(Br)cc3)cc21", "C[C@@H]1C[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(-c4ccccn4)cc3)C[C@]2(C)[C@H]1C(=O)C1CC1", "CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)C(=O)NCCCCCC(=O)N[C@@H](CC(C)C)C(=O)OC(C)(C)C)cc3)C[C@@]21C", "CN(C)c1ccc([C@H]2OC[C@]3(C)[C@@H](O)CC[C@H]3[C@@H]3CCC4=CC(=O)CCC4=C32)cc1", "CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)CCC(=O)Nc4ccc(C(N)=O)c(O)c4)cc3)C[C@@]21C", "CC1=CC(C)(C)Nc2ccc3c(c21)COc1c(Cl)cccc1-3", "C=C1CCO[C@]12CC[C@H]1[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)C)cc3)OC[C@@]12C", "CC(c1nnnn1C(C)C)N(Cc1ccccc1Cl)c1ccc(C#N)c(Cl)c1", "C=C1C(C)=CCC(C)(C)[C@@H]1Cc1cc(OC)c(Br)cc1OC(C)=O", "CC1=CC(C)(C)Nc2ccc3c(c21)/C(=C/C=O)Oc1ccc(F)cc1-3", "C=C1C=C(C)CC(C)(C)C1Sc1ccc([N+](=O)[O-])cc1", "CCCCn1c2ccccc2c2ccc3c(c21)C(C)=CC(C)(C)N3", "CC(C)CC(c1nnnn1C)N(CC(C)C)c1ccc(C#N)c(Cl)c1", "C=C1CCCC(C)(C)C1Cc1cc(OC)c(Br)cc1O", "COc1ccc(-c2ccc([C@H]3C[C@]4(C)[C@@H](C(=O)C5CC5)CC[C@H]4[C@@H]4CCC5=CC(=O)CCC5=C43)cc2)cn1", "CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)CCCCCC=O)cc3)C[C@@]21C", "CCC1(CC)OC(=O)N(C)c2ccc(Nc3cccc(Cl)c3)cc21", "CN(C)c1ccc([C@H]2C[C@]3(C)[C@@H](CC[C@]3(O)CCCO)[C@@H]3CCC4=CC(=O)CCC4=C32)cc1", "COc1ccccc1-c1ccc2c(c1)C(C(C)OCCc1cccc(Cl)c1)=CC(C)(C)N2", "CC1(C)[C@H](O)CC[C@]2(C)[C@@]3(C)c4[nH]c5ccccc5c4C[C@@H]3CC[C@@]12O", "CC(c1cn(C)nn1)N(Cc1ccccc1Cl)c1ccc(C#N)c(Cl)c1", "CC1(C)OC(C(C)(C)C)Nc2ccc(-c3cc(F)cc(C#N)c3)cc21", "CC1=CC(C)(C)Nc2cc3oc4ccccc4c3cc21", "O=[N+]([O-])c1cccc(-c2ccc3nc(S)n(Cc4ccccc4)c3c2)c1", "O=C(c1ccc([N+](=O)[O-])cc1)N1CCCC(c2ccc(Cl)c(Cl)c2)=N1", "CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)C(=O)NCCCC)cc3)C[C@@]21C", "C=C1C(C)=CCC(C)(C)[C@@H]1Cc1cc(OC)c(Br)cc1OC(C)=O", "CN(C)c1ccc([C@H]2C[C@]3(C)[C@@H](CC[C@]3(O)CCCO)[C@@H]3CCC4=CC(=O)CCC4=C32)cc1", "CC1=CC(C)(C)Nc2ccc(-c3ccsc3C#N)cc21", "CC#C[C@]1(O)CC[C@H]2[C@@H]3CCC4=CC(=O)CCC4=C3[C@@H](c3ccc(N(C)CCCCCCCC(=O)OC)cc3)C[C@@]21C", "CCC1(CC)OC(=O)N(C)c2ccc(Nc3cccc(Cl)c3Cl)cc21", "CC1(C)C(=O)Nc2ccc(-c3cc(F)cc(Cl)c3)cc21", "C[C@@H]1c2c(ccc3c2[C@H](c2ccc(Cl)cc2)Oc2ccccc2-3)NC(C)(C)[C@H]1O"], "colorscale": "Portland"}" style="width: 100%; height: 100%; display:inline-block;"></div>
</body>
</meta>
<script>var plot = document.getElementById("basevis-entry");
var hoverInfo = document.getElementById("basevis-entry2");
var data = JSON.parse(document.getElementById("basevis-entry").dataset.visdata);
let options = {};
let smilesDrawer = new SmilesDrawer.Drawer(options);
var trace = {
x: data.X,
y: data.Y,
text: data.SMILES,
mode: "markers",
type: "scatter",
hoverinfo: "none",
marker: {},
};
if ("hovertext" in data) {
trace.hovertext = data.hovertext;
trace.hoverinfo = "text";
}
if ("group" in data) {
trace.transforms = [{ type: "groupby", groups: data.group }];
}
if ("hovertemplate" in data) {
trace.hovertemplate = data.hovertemplate;
}
if ("color" in data) {
trace.marker.color = data.color;
}
if ("size" in data) {
trace.marker.size = data.size;
} else {
trace.marker.size = 12;
}
// if ("outline" in data) {
// trace.marker.line = {
// color: data.outline,
// width: 4,
// };
// }
if ("opacity" in data) {
trace.marker.opacity = data.opacity;
}
var plot_data = [trace];
var layout = {
title: "Plot Title",
xaxis: {
title: "x Axis",
},
yaxis: {
title: "y Axis",
},
width: data.width,
height: data.height,
autosize: true,
};
if ("title" in data) {
layout.title = data.title;
}
if ("xaxis_title" in data) {
layout.xaxis.title = data.xaxis_title;
}
if ("yaxis_title" in data) {
layout.yaxis.title = data.yaxis_title;
}
layout.xaxis.type = data["xaxis_type"];
layout.yaxis.type = data["yaxis_type"];
if ("ydomain" in data){
layout.yaxis.domain = data.ydomain;
}
if ("xdomain" in data){
layout.xaxis.domain = data.xdomain;
}
if ("yrange" in data){
layout.yaxis.range = data.yrange;
}
if ("xrange" in data){
layout.xaxis.range = data.xrange;
}
if ("axesratio" in data){
layout.yaxis.scaleanchor = "x";
layout.yaxis.scaleratio = data.axesratio;
}
if ("xdtick" in data){
layout.xaxis.dtick = data.xdtick;
}
if ("ydtick" in data){
layout.yaxis.dtick = data.ydtick;
}
if ("color" in data) {
if ("colorscale" in data) {
trace.colorscale = data.colorscale;
trace.marker.colorscale = data.colorscale;
trace.marker.colorbar = {
title: "",
titleside: "top",
};
}
}
Plotly.newPlot(
"basevis-entry",
plot_data,
layout,
(config = {
displaylogo: false,
modeBarButtonsToRemove: ["zoom2d", "pan2d", "select2d", "lasso2d"],
})
);
if ("layout_update" in data){
Plotly.update("basevis-entry", {}, data.layout_update);
}
if ("trace_update" in data){
Plotly.addTraces("basevis-entry", data.trace_update);
}
const hoverCanvas = document.createElement("canvas");
hoverCanvas.id = "hoverCanvas";
const hoverBackground = document.createElement("canvas");
hoverBackground.id = "hoverBackground";
var hoverSize = parseFloat(data.hover_size);
plot.appendChild(hoverCanvas);
plot.appendChild(hoverBackground);
plot
.on("plotly_hover", function (data) {
var xaxis = data.points[0].xaxis,
yaxis = data.points[0].yaxis;
data.points.map(function (d) {
hoverCanvas.hidden = false;
hoverBackground.hidden = false;
ctx = hoverCanvas.getContext("2d");
SmilesDrawer.parse(d.text, function (smiles) {
smilesDrawer.draw(smiles, "hoverCanvas", "light", false);
});
ctx.fillStyle = "black";
ctx.shadowColor = "black";
ctx.shadowBlur = 20;
ctx.lineJoin = "bevel";
ctx.lineWidth = 15;
ctx.strokeRect(0, 0, hoverCanvas.width, hoverCanvas.height, "light");
hoverBackground.width = hoverCanvas.width;
hoverBackground.height = hoverCanvas.height;
ctx = hoverBackground.getContext("2d");
ctx.fillStyle = "white";
ctx.fillRect(0, 0, hoverBackground.width, hoverBackground.height);
Plotly.update(
"basevis-entry",
{},
{
// margin: { t: 100, b: 100, l: 50, r: 50 },
annotations: [
{
x: d.x,
y: d.y,
xref: "x",
yref: "y",
text: "",
showarrow: true,
arrowhead: 7,
ax: 0,
ay: 0,
},
],
images: [
{
x: (d.x - xaxis.range[0]) / (xaxis.range[1] - xaxis.range[0]),
y: (d.y - yaxis.range[0]) / (yaxis.range[1] - yaxis.range[0]),
sizex: hoverSize,
sizey: hoverSize,
xref: "paper",
yref: "paper",
source: document.getElementById("hoverBackground").toDataURL(),
xanchor: "left",
yanchor: "top",
layer: "above",
},
{
x: (d.x - xaxis.range[0]) / (xaxis.range[1] - xaxis.range[0]),
y: (d.y - yaxis.range[0]) / (yaxis.range[1] - yaxis.range[0]),
sizex: hoverSize,
sizey: hoverSize,
xref: "paper",
yref: "paper",
source: document.getElementById("hoverCanvas").toDataURL(),
xanchor: "left",
yanchor: "top",
layer: "above",
},
],
}
);
hoverCanvas.hidden = true;
hoverBackground.hidden = true;
});
})
.on("plotly_unhover", function (data) {
Plotly.update("basevis-entry", {}, { annotations: [], images: [] });
});
</script><script> window.addEventListener("resize", function(){if (document.getElementById("basevis-entry")) {Plotly.Plots.resize(document.getElementById("basevis-entry"));};}) </script>
'data:text/html,%0A%20%20%20%20%20%20%20%20%3C%21DOCTYPE%20html%3E%0A%20%20%20%20%20%20%20%20%3Chead%3E%0A%20%20%20%20%20%20%20%20%3Cmeta%20charset%3D%22utf-8%22%3E%0A%20%20%20%20%20%20%20%20%3C%2Fhead%3E%0A%0A%20%20%20%20%20%20%20%20%3Chtml%20style%3D%22height%3A%20100%25%3B%22%3E%0A%0A%20%20%20%20%20%20%20%20%3C%21--%20Load%20packages%20--%3E%0A%20%20%20%20%20%20%20%20%3Cscript%20src%3D%22https%3A%2F%2Fcdn.plot.ly%2Fplotly-2.12.1.min.js%22%3E%3C%2Fscript%3E%3Cscript%20src%3D%22https%3A%2F%2Funpkg.com%2Fsmiles-drawer%401.0.10%2Fdist%2Fsmiles-drawer.min.js%22%3E%3C%2Fscript%3E%0A%20%20%20%20%20%20%20%20%3Cbody%20style%3D%22background-color%3A%23FFFFFF%3B%20height%3A%20100%25%3B%22%3E%0A%20%20%20%20%20%20%20%20%3C%21--%20Create%20a%20div%20where%20the%20graph%20will%20take%20place%20--%3E%0A%20%20%20%20%20%20%20%20%3Cdiv%20id%3D%22basevis-entry%22%20data-visdata%3D%22%7B%26quot%3Btitle%26quot%3B%3A%20%26quot%3BChemical%20Space%20Plot%26quot%3B%2C%20%26quot%3Bxaxis_title%26quot%3B%3A%20%26quot%3BComponent%201%26quot%3B%2C%20%26quot%3Byaxis_title%26quot%3B%3A%20%26quot%3BComponent%202%26quot%3B%2C%20%26quot%3Bhover_size%26quot%3B%3A%200.4%2C%20%26quot%3Bxaxis_type%26quot%3B%3A%20%26quot%3Blinear%26quot%3B%2C%20%26quot%3Byaxis_type%26quot%3B%3A%20%26quot%3Blinear%26quot%3B%2C%20%26quot%3Bwidth%26quot%3B%3A%20800%2C%20%26quot%3Bheight%26quot%3B%3A%20600%2C%20%26quot%3Bopacity%26quot%3B%3A%201%2C%20%26quot%3BX%26quot%3B%3A%20%5B43.61760330200195%2C%20-17.472150802612305%2C%2041.86582946777344%2C%20158.97496032714844%2C%20-24.860200881958008%2C%20-2.232616424560547%2C%20-35.85402297973633%2C%20-67.47518157958984%2C%2055.304420471191406%2C%20-13.724129676818848%2C%20-3.4850451946258545%2C%20-134.3723602294922%2C%20-62.69178771972656%2C%2030.23807716369629%2C%20-5.901937961578369%2C%2010.940505981445312%2C%20-4.623172283172607%2C%20-43.74485778808594%2C%208.369648933410645%2C%2068.97262573242188%2C%20-22.280351638793945%2C%20-30.012405395507812%2C%2075.25151062011719%2C%2064.52973937988281%2C%20-3.1073720455169678%2C%20-26.3098087310791%2C%20-29.127517700195312%2C%2014.045056343078613%2C%2027.511388778686523%2C%2062.6290168762207%2C%2046.29264831542969%2C%2018.152881622314453%2C%2049.81310272216797%2C%20-81.98030853271484%2C%2041.48120880126953%2C%2089.24085998535156%2C%2027.849729537963867%2C%20-41.686649322509766%2C%2026.67981719970703%2C%20-6.256188869476318%2C%20-26.8016300201416%2C%208.647194862365723%2C%20-49.416343688964844%2C%20-42.954734802246094%2C%2048.0875129699707%2C%20-25.647356033325195%2C%2023.574270248413086%2C%20-62.410926818847656%2C%2012.529644966125488%5D%2C%20%26quot%3BY%26quot%3B%3A%20%5B-37.546878814697266%2C%20-26.210065841674805%2C%20-12.783864974975586%2C%2027.13193702697754%2C%2087.86702728271484%2C%20-81.90585327148438%2C%20-47.80723571777344%2C%2036.506431579589844%2C%20-61.465553283691406%2C%20-56.813961029052734%2C%20-39.14337921142578%2C%2076.40354919433594%2C%20-47.68071746826172%2C%206.304887294769287%2C%2061.944801330566406%2C%2044.215999603271484%2C%20-10.914501190185547%2C%2059.72188949584961%2C%20-62.289512634277344%2C%2021.70496940612793%2C%2030.97284507751465%2C%20-73.79450225830078%2C%20-1.874199628829956%2C%2044.48176956176758%2C%2031.48701286315918%2C%2050.19774627685547%2C%20149.90878295898438%2C%20-6.158529281616211%2C%2032.54773712158203%2C%20-22.430017471313477%2C%2033.658206939697266%2C%2067.7158432006836%2C%206.881969451904297%2C%201.560334324836731%2C%2059.63355255126953%2C%20-42.17106246948242%2C%20-72.33515930175781%2C%20-26.811941146850586%2C%20-24.993431091308594%2C%2010.065010070800781%2C%20-9.101613998413086%2C%20-25.244958877563477%2C%201.6200640201568604%2C%2022.73969841003418%2C%20-87.27729034423828%2C%209.062121391296387%2C%20-48.46100997924805%2C%20-18.139448165893555%2C%2014.488275527954102%5D%2C%20%26quot%3BSMILES%26quot%3B%3A%20%5B%26quot%3BCC%28C%29CC%28c1nnnn1C%29N%28Cc1ccccc1Cl%29c1ccc%28C%23N%29c%28Cl%29c1%26quot%3B%2C%20%26quot%3BCc1c%28NS%28C%29%28%3DO%29%3DO%29cccc1N%28Cc1ccccc1%29Cc1ccc%28Oc2ccc%28OCC%28%3DO%29O%29cc2%29cc1%26quot%3B%2C%20%26quot%3BC%3DC%28C%29%5BC%40%5D1%28O%29CC%5BC%40H%5D2%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC3%5BC%40%40H%5D%28c3ccc%28SC%29cc3%29OC%5BC%40%40%5D21C%26quot%3B%2C%20%26quot%3BCC%28C%29N1C%28%3DO%29OC%28C%29%28C%29c2cc%28Nc3ccc%28Br%29cc3%29ccc21%26quot%3B%2C%20%26quot%3BCS%28%3DO%29%28%3DO%29Nc1ccc2c%28c1%29C%28c1ccccc1%29Oc1cccc%28OC%28F%29F%29c1-2%26quot%3B%2C%20%26quot%3BCC%23C%5BC%40%5D1%28O%29CC%5BC%40H%5D2%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC3%5BC%40%40H%5D%28c3ccc%28N%28C%29CCC%28%3DO%29O%29cc3%29C%5BC%40%40%5D21C%26quot%3B%2C%20%26quot%3BCC%23C%5BC%40%5D1%28O%29CC%5BC%40H%5D2%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC3%5BC%40%40H%5D%28c3ccc%28NC%29cc3%29C%5BC%40%40%5D21C%26quot%3B%2C%20%26quot%3BCCn1nnnc1C%28C%29N%28Cc1ccccc1Cl%29c1ccc%28C%23N%29c%28Cl%29c1%26quot%3B%2C%20%26quot%3BCC1%28C%29OC%28%3DO%29Nc2ccc%28-c3ccc%28F%29c%28C%23N%29c3%29cc21%26quot%3B%2C%20%26quot%3BCN1C%28%3DO%29OC%28C%29%28C%29c2cc%28Nc3cccc%28Cl%29c3Cl%29ccc21%26quot%3B%2C%20%26quot%3BCCOc1cccc2c1-c1ccc%28NS%28C%29%28%3DO%29%3DO%29cc1C%28c1ccccc1%29O2%26quot%3B%2C%20%26quot%3BCC%23C%5BC%40%5D1%28O%29CC%5BC%40H%5D2%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC3%5BC%40%40H%5D%28c3ccc%28N%28C%29CCCCCC%29cc3%29C%5BC%40%40%5D21C%26quot%3B%2C%20%26quot%3BCn1nnnc1CN%28Cc1ccccc1Cl%29c1ccc%28C%23N%29c%28Cl%29c1%26quot%3B%2C%20%26quot%3BC%3DC1C%3DC%28C%29CC%28C%29%28C%29C1Cc1ccc%28%5BN%2B%5D%28%3DO%29%5BO-%5D%29cc1%26quot%3B%2C%20%26quot%3BCC%23C%5BC%40%5D1%28O%29CC%5BC%40H%5D2%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC3%5BC%40%40H%5D%28c3ccc%28N%28C%29C%29cc3%29C%5BC%40%40%5D21C%26quot%3B%2C%20%26quot%3BCC%23C%5BC%40%5D1%28O%29CC%5BC%40H%5D2%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC3%5BC%40%40H%5D%28c3ccc%28N%28C%29C%29cc3%29C%5BC%40%40%5D21C%26quot%3B%2C%20%26quot%3BCC1%28C%29OC%28%3DO%29N%28Cc2ccccc2%29c2ccc%28Nc3ccc%28Br%29cc3%29cc21%26quot%3B%2C%20%26quot%3BC%5BC%40%40H%5D1C%5BC%40H%5D2%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC3%5BC%40%40H%5D%28c3ccc%28-c4ccccn4%29cc3%29C%5BC%40%5D2%28C%29%5BC%40H%5D1C%28%3DO%29C1CC1%26quot%3B%2C%20%26quot%3BCC%23C%5BC%40%5D1%28O%29CC%5BC%40H%5D2%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC3%5BC%40%40H%5D%28c3ccc%28N%28C%29C%28%3DO%29NCCCCCC%28%3DO%29N%5BC%40%40H%5D%28CC%28C%29C%29C%28%3DO%29OC%28C%29%28C%29C%29cc3%29C%5BC%40%40%5D21C%26quot%3B%2C%20%26quot%3BCN%28C%29c1ccc%28%5BC%40H%5D2OC%5BC%40%5D3%28C%29%5BC%40%40H%5D%28O%29CC%5BC%40H%5D3%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC32%29cc1%26quot%3B%2C%20%26quot%3BCC%23C%5BC%40%5D1%28O%29CC%5BC%40H%5D2%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC3%5BC%40%40H%5D%28c3ccc%28N%28C%29CCC%28%3DO%29Nc4ccc%28C%28N%29%3DO%29c%28O%29c4%29cc3%29C%5BC%40%40%5D21C%26quot%3B%2C%20%26quot%3BCC1%3DCC%28C%29%28C%29Nc2ccc3c%28c21%29COc1c%28Cl%29cccc1-3%26quot%3B%2C%20%26quot%3BC%3DC1CCO%5BC%40%5D12CC%5BC%40H%5D1%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC3%5BC%40%40H%5D%28c3ccc%28N%28C%29C%29cc3%29OC%5BC%40%40%5D12C%26quot%3B%2C%20%26quot%3BCC%28c1nnnn1C%28C%29C%29N%28Cc1ccccc1Cl%29c1ccc%28C%23N%29c%28Cl%29c1%26quot%3B%2C%20%26quot%3BC%3DC1C%28C%29%3DCCC%28C%29%28C%29%5BC%40%40H%5D1Cc1cc%28OC%29c%28Br%29cc1OC%28C%29%3DO%26quot%3B%2C%20%26quot%3BCC1%3DCC%28C%29%28C%29Nc2ccc3c%28c21%29%2FC%28%3DC%2FC%3DO%29Oc1ccc%28F%29cc1-3%26quot%3B%2C%20%26quot%3BC%3DC1C%3DC%28C%29CC%28C%29%28C%29C1Sc1ccc%28%5BN%2B%5D%28%3DO%29%5BO-%5D%29cc1%26quot%3B%2C%20%26quot%3BCCCCn1c2ccccc2c2ccc3c%28c21%29C%28C%29%3DCC%28C%29%28C%29N3%26quot%3B%2C%20%26quot%3BCC%28C%29CC%28c1nnnn1C%29N%28CC%28C%29C%29c1ccc%28C%23N%29c%28Cl%29c1%26quot%3B%2C%20%26quot%3BC%3DC1CCCC%28C%29%28C%29C1Cc1cc%28OC%29c%28Br%29cc1O%26quot%3B%2C%20%26quot%3BCOc1ccc%28-c2ccc%28%5BC%40H%5D3C%5BC%40%5D4%28C%29%5BC%40%40H%5D%28C%28%3DO%29C5CC5%29CC%5BC%40H%5D4%5BC%40%40H%5D4CCC5%3DCC%28%3DO%29CCC5%3DC43%29cc2%29cn1%26quot%3B%2C%20%26quot%3BCC%23C%5BC%40%5D1%28O%29CC%5BC%40H%5D2%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC3%5BC%40%40H%5D%28c3ccc%28N%28C%29CCCCCC%3DO%29cc3%29C%5BC%40%40%5D21C%26quot%3B%2C%20%26quot%3BCCC1%28CC%29OC%28%3DO%29N%28C%29c2ccc%28Nc3cccc%28Cl%29c3%29cc21%26quot%3B%2C%20%26quot%3BCN%28C%29c1ccc%28%5BC%40H%5D2C%5BC%40%5D3%28C%29%5BC%40%40H%5D%28CC%5BC%40%5D3%28O%29CCCO%29%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC32%29cc1%26quot%3B%2C%20%26quot%3BCOc1ccccc1-c1ccc2c%28c1%29C%28C%28C%29OCCc1cccc%28Cl%29c1%29%3DCC%28C%29%28C%29N2%26quot%3B%2C%20%26quot%3BCC1%28C%29%5BC%40H%5D%28O%29CC%5BC%40%5D2%28C%29%5BC%40%40%5D3%28C%29c4%5BnH%5Dc5ccccc5c4C%5BC%40%40H%5D3CC%5BC%40%40%5D12O%26quot%3B%2C%20%26quot%3BCC%28c1cn%28C%29nn1%29N%28Cc1ccccc1Cl%29c1ccc%28C%23N%29c%28Cl%29c1%26quot%3B%2C%20%26quot%3BCC1%28C%29OC%28C%28C%29%28C%29C%29Nc2ccc%28-c3cc%28F%29cc%28C%23N%29c3%29cc21%26quot%3B%2C%20%26quot%3BCC1%3DCC%28C%29%28C%29Nc2cc3oc4ccccc4c3cc21%26quot%3B%2C%20%26quot%3BO%3D%5BN%2B%5D%28%5BO-%5D%29c1cccc%28-c2ccc3nc%28S%29n%28Cc4ccccc4%29c3c2%29c1%26quot%3B%2C%20%26quot%3BO%3DC%28c1ccc%28%5BN%2B%5D%28%3DO%29%5BO-%5D%29cc1%29N1CCCC%28c2ccc%28Cl%29c%28Cl%29c2%29%3DN1%26quot%3B%2C%20%26quot%3BCC%23C%5BC%40%5D1%28O%29CC%5BC%40H%5D2%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC3%5BC%40%40H%5D%28c3ccc%28N%28C%29C%28%3DO%29NCCCC%29cc3%29C%5BC%40%40%5D21C%26quot%3B%2C%20%26quot%3BC%3DC1C%28C%29%3DCCC%28C%29%28C%29%5BC%40%40H%5D1Cc1cc%28OC%29c%28Br%29cc1OC%28C%29%3DO%26quot%3B%2C%20%26quot%3BCN%28C%29c1ccc%28%5BC%40H%5D2C%5BC%40%5D3%28C%29%5BC%40%40H%5D%28CC%5BC%40%5D3%28O%29CCCO%29%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC32%29cc1%26quot%3B%2C%20%26quot%3BCC1%3DCC%28C%29%28C%29Nc2ccc%28-c3ccsc3C%23N%29cc21%26quot%3B%2C%20%26quot%3BCC%23C%5BC%40%5D1%28O%29CC%5BC%40H%5D2%5BC%40%40H%5D3CCC4%3DCC%28%3DO%29CCC4%3DC3%5BC%40%40H%5D%28c3ccc%28N%28C%29CCCCCCCC%28%3DO%29OC%29cc3%29C%5BC%40%40%5D21C%26quot%3B%2C%20%26quot%3BCCC1%28CC%29OC%28%3DO%29N%28C%29c2ccc%28Nc3cccc%28Cl%29c3Cl%29cc21%26quot%3B%2C%20%26quot%3BCC1%28C%29C%28%3DO%29Nc2ccc%28-c3cc%28F%29cc%28Cl%29c3%29cc21%26quot%3B%2C%20%26quot%3BC%5BC%40%40H%5D1c2c%28ccc3c2%5BC%40H%5D%28c2ccc%28Cl%29cc2%29Oc2ccccc2-3%29NC%28C%29%28C%29%5BC%40H%5D1O%26quot%3B%5D%2C%20%26quot%3Bcolorscale%26quot%3B%3A%20%26quot%3BPortland%26quot%3B%7D%22%20style%3D%22width%3A%20100%25%3B%20height%3A%20100%25%3B%20display%3Ainline-block%3B%22%3E%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%3C%2Fbody%3E%0A%20%20%20%20%20%20%20%20%3C%2Fmeta%3E%0A%20%20%20%20%20%20%20%20%3Cscript%3Evar%20plot%20%3D%20document.getElementById%28%22basevis-entry%22%29%3B%0Avar%20hoverInfo%20%3D%20document.getElementById%28%22basevis-entry2%22%29%3B%0A%0Avar%20data%20%3D%20JSON.parse%28document.getElementById%28%22basevis-entry%22%29.dataset.visdata%29%3B%0A%0Alet%20options%20%3D%20%7B%7D%3B%0Alet%20smilesDrawer%20%3D%20new%20SmilesDrawer.Drawer%28options%29%3B%0A%0Avar%20trace%20%3D%20%7B%0A%20%20x%3A%20data.X%2C%0A%20%20y%3A%20data.Y%2C%0A%20%20text%3A%20data.SMILES%2C%0A%20%20mode%3A%20%22markers%22%2C%0A%20%20type%3A%20%22scatter%22%2C%0A%20%20hoverinfo%3A%20%22none%22%2C%0A%20%20marker%3A%20%7B%7D%2C%0A%7D%3B%0A%0Aif%20%28%22hovertext%22%20in%20data%29%20%7B%0A%20%20trace.hovertext%20%3D%20data.hovertext%3B%0A%20%20trace.hoverinfo%20%3D%20%22text%22%3B%0A%7D%0A%0Aif%20%28%22group%22%20in%20data%29%20%7B%0A%20%20trace.transforms%20%3D%20%5B%7B%20type%3A%20%22groupby%22%2C%20groups%3A%20data.group%20%7D%5D%3B%0A%7D%0A%0Aif%20%28%22hovertemplate%22%20in%20data%29%20%7B%0A%20%20trace.hovertemplate%20%3D%20data.hovertemplate%3B%0A%7D%0A%0Aif%20%28%22color%22%20in%20data%29%20%7B%0A%20%20trace.marker.color%20%3D%20data.color%3B%0A%7D%0A%0Aif%20%28%22size%22%20in%20data%29%20%7B%0A%20%20trace.marker.size%20%3D%20data.size%3B%0A%7D%20else%20%7B%0A%20%20trace.marker.size%20%3D%2012%3B%0A%7D%0A%0A%2F%2F%20if%20%28%22outline%22%20in%20data%29%20%7B%0A%2F%2F%20%20%20trace.marker.line%20%3D%20%7B%0A%2F%2F%20%20%20%20%20color%3A%20data.outline%2C%0A%2F%2F%20%20%20%20%20width%3A%204%2C%0A%2F%2F%20%20%20%7D%3B%0A%2F%2F%20%7D%0A%0Aif%20%28%22opacity%22%20in%20data%29%20%7B%0A%20%20trace.marker.opacity%20%3D%20data.opacity%3B%0A%7D%0A%0Avar%20plot_data%20%3D%20%5Btrace%5D%3B%0A%0Avar%20layout%20%3D%20%7B%0A%20%20title%3A%20%22Plot%20Title%22%2C%0A%20%20xaxis%3A%20%7B%0A%20%20%20%20title%3A%20%22x%20Axis%22%2C%0A%20%20%7D%2C%0A%20%20yaxis%3A%20%7B%0A%20%20%20%20title%3A%20%22y%20Axis%22%2C%0A%20%20%7D%2C%0A%20%20width%3A%20data.width%2C%0A%20%20height%3A%20data.height%2C%0A%20%20autosize%3A%20true%2C%0A%7D%3B%0A%0Aif%20%28%22title%22%20in%20data%29%20%7B%0A%20%20layout.title%20%3D%20data.title%3B%0A%7D%0A%0Aif%20%28%22xaxis_title%22%20in%20data%29%20%7B%0A%20%20layout.xaxis.title%20%3D%20data.xaxis_title%3B%0A%7D%0A%0Aif%20%28%22yaxis_title%22%20in%20data%29%20%7B%0A%20%20layout.yaxis.title%20%3D%20data.yaxis_title%3B%0A%7D%0A%0Alayout.xaxis.type%20%3D%20data%5B%22xaxis_type%22%5D%3B%0Alayout.yaxis.type%20%3D%20data%5B%22yaxis_type%22%5D%3B%0A%0Aif%20%28%22ydomain%22%20in%20data%29%7B%0A%20%20layout.yaxis.domain%20%3D%20data.ydomain%3B%0A%7D%0Aif%20%28%22xdomain%22%20in%20data%29%7B%0A%20%20layout.xaxis.domain%20%3D%20data.xdomain%3B%0A%7D%0A%0Aif%20%28%22yrange%22%20in%20data%29%7B%0A%20%20layout.yaxis.range%20%3D%20data.yrange%3B%0A%7D%0Aif%20%28%22xrange%22%20in%20data%29%7B%0A%20%20layout.xaxis.range%20%3D%20data.xrange%3B%0A%7D%0A%0Aif%20%28%22axesratio%22%20in%20data%29%7B%0A%20%20layout.yaxis.scaleanchor%20%3D%20%22x%22%3B%0A%20%20layout.yaxis.scaleratio%20%3D%20data.axesratio%3B%0A%7D%0A%0Aif%20%28%22xdtick%22%20in%20data%29%7B%0A%20%20layout.xaxis.dtick%20%3D%20data.xdtick%3B%0A%7D%0A%0Aif%20%28%22ydtick%22%20in%20data%29%7B%0A%20%20layout.yaxis.dtick%20%3D%20data.ydtick%3B%0A%7D%0A%0Aif%20%28%22color%22%20in%20data%29%20%7B%0A%20%20if%20%28%22colorscale%22%20in%20data%29%20%7B%0A%20%20%20%20trace.colorscale%20%3D%20data.colorscale%3B%0A%20%20%20%20trace.marker.colorscale%20%3D%20data.colorscale%3B%0A%20%20%20%20trace.marker.colorbar%20%3D%20%7B%0A%20%20%20%20%20%20title%3A%20%22%22%2C%0A%20%20%20%20%20%20titleside%3A%20%22top%22%2C%0A%20%20%20%20%7D%3B%0A%20%20%7D%0A%7D%0A%0APlotly.newPlot%28%0A%20%20%22basevis-entry%22%2C%0A%20%20plot_data%2C%0A%20%20layout%2C%0A%20%20%28config%20%3D%20%7B%0A%20%20%20%20displaylogo%3A%20false%2C%0A%20%20%20%20modeBarButtonsToRemove%3A%20%5B%22zoom2d%22%2C%20%22pan2d%22%2C%20%22select2d%22%2C%20%22lasso2d%22%5D%2C%0A%20%20%7D%29%0A%29%3B%0A%0Aif%20%28%22layout_update%22%20in%20data%29%7B%0A%20%20Plotly.update%28%22basevis-entry%22%2C%20%7B%7D%2C%20data.layout_update%29%3B%0A%7D%0A%0Aif%20%28%22trace_update%22%20in%20data%29%7B%0A%20%20Plotly.addTraces%28%22basevis-entry%22%2C%20data.trace_update%29%3B%0A%7D%0A%0Aconst%20hoverCanvas%20%3D%20document.createElement%28%22canvas%22%29%3B%0AhoverCanvas.id%20%3D%20%22hoverCanvas%22%3B%0A%0Aconst%20hoverBackground%20%3D%20document.createElement%28%22canvas%22%29%3B%0AhoverBackground.id%20%3D%20%22hoverBackground%22%3B%0A%0Avar%20hoverSize%20%3D%20parseFloat%28data.hover_size%29%3B%0A%0Aplot.appendChild%28hoverCanvas%29%3B%0Aplot.appendChild%28hoverBackground%29%3B%0A%0Aplot%0A%20%20.on%28%22plotly_hover%22%2C%20function%20%28data%29%20%7B%0A%20%20%20%20var%20xaxis%20%3D%20data.points%5B0%5D.xaxis%2C%0A%20%20%20%20%20%20yaxis%20%3D%20data.points%5B0%5D.yaxis%3B%0A%0A%20%20%20%20data.points.map%28function%20%28d%29%20%7B%0A%20%20%20%20%20%20hoverCanvas.hidden%20%3D%20false%3B%0A%20%20%20%20%20%20hoverBackground.hidden%20%3D%20false%3B%0A%0A%20%20%20%20%20%20ctx%20%3D%20hoverCanvas.getContext%28%222d%22%29%3B%0A%0A%20%20%20%20%20%20SmilesDrawer.parse%28d.text%2C%20function%20%28smiles%29%20%7B%0A%20%20%20%20%20%20%20%20smilesDrawer.draw%28smiles%2C%20%22hoverCanvas%22%2C%20%22light%22%2C%20false%29%3B%0A%20%20%20%20%20%20%7D%29%3B%0A%0A%20%20%20%20%20%20ctx.fillStyle%20%3D%20%22black%22%3B%0A%20%20%20%20%20%20ctx.shadowColor%20%3D%20%22black%22%3B%0A%20%20%20%20%20%20ctx.shadowBlur%20%3D%2020%3B%0A%20%20%20%20%20%20ctx.lineJoin%20%3D%20%22bevel%22%3B%0A%20%20%20%20%20%20ctx.lineWidth%20%3D%2015%3B%0A%20%20%20%20%20%20ctx.strokeRect%280%2C%200%2C%20hoverCanvas.width%2C%20hoverCanvas.height%2C%20%22light%22%29%3B%0A%0A%20%20%20%20%20%20hoverBackground.width%20%3D%20hoverCanvas.width%3B%0A%20%20%20%20%20%20hoverBackground.height%20%3D%20hoverCanvas.height%3B%0A%20%20%20%20%20%20ctx%20%3D%20hoverBackground.getContext%28%222d%22%29%3B%0A%20%20%20%20%20%20ctx.fillStyle%20%3D%20%22white%22%3B%0A%20%20%20%20%20%20ctx.fillRect%280%2C%200%2C%20hoverBackground.width%2C%20hoverBackground.height%29%3B%0A%0A%20%20%20%20%20%20Plotly.update%28%0A%20%20%20%20%20%20%20%20%22basevis-entry%22%2C%0A%20%20%20%20%20%20%20%20%7B%7D%2C%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%2F%2F%20margin%3A%20%7B%20t%3A%20100%2C%20b%3A%20100%2C%20l%3A%2050%2C%20r%3A%2050%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20annotations%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%3A%20d.x%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20y%3A%20d.y%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20xref%3A%20%22x%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20yref%3A%20%22y%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20showarrow%3A%20true%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20arrowhead%3A%207%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20ax%3A%200%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20ay%3A%200%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%20%20images%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%3A%20%28d.x%20-%20xaxis.range%5B0%5D%29%20%2F%20%28xaxis.range%5B1%5D%20-%20xaxis.range%5B0%5D%29%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20y%3A%20%28d.y%20-%20yaxis.range%5B0%5D%29%20%2F%20%28yaxis.range%5B1%5D%20-%20yaxis.range%5B0%5D%29%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20sizex%3A%20hoverSize%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20sizey%3A%20hoverSize%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20xref%3A%20%22paper%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20yref%3A%20%22paper%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20source%3A%20document.getElementById%28%22hoverBackground%22%29.toDataURL%28%29%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20xanchor%3A%20%22left%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20yanchor%3A%20%22top%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20layer%3A%20%22above%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%3A%20%28d.x%20-%20xaxis.range%5B0%5D%29%20%2F%20%28xaxis.range%5B1%5D%20-%20xaxis.range%5B0%5D%29%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20y%3A%20%28d.y%20-%20yaxis.range%5B0%5D%29%20%2F%20%28yaxis.range%5B1%5D%20-%20yaxis.range%5B0%5D%29%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20sizex%3A%20hoverSize%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20sizey%3A%20hoverSize%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20xref%3A%20%22paper%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20yref%3A%20%22paper%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20source%3A%20document.getElementById%28%22hoverCanvas%22%29.toDataURL%28%29%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20xanchor%3A%20%22left%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20yanchor%3A%20%22top%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20layer%3A%20%22above%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%29%3B%0A%20%20%20%20%20%20hoverCanvas.hidden%20%3D%20true%3B%0A%20%20%20%20%20%20hoverBackground.hidden%20%3D%20true%3B%0A%20%20%20%20%7D%29%3B%0A%20%20%7D%29%0A%20%20.on%28%22plotly_unhover%22%2C%20function%20%28data%29%20%7B%0A%20%20%20%20Plotly.update%28%22basevis-entry%22%2C%20%7B%7D%2C%20%7B%20annotations%3A%20%5B%5D%2C%20images%3A%20%5B%5D%20%7D%29%3B%0A%20%20%7D%29%3B%0A%3C%2Fscript%3E%3Cscript%3E%20window.addEventListener%28%22resize%22%2C%20function%28%29%7Bif%20%28document.getElementById%28%22basevis-entry%22%29%29%20%7BPlotly.Plots.resize%28document.getElementById%28%22basevis-entry%22%29%29%3B%7D%3B%7D%29%20%3C%2Fscript%3E'