Package: faerun
Faerun (Python)Faerun (Python) is based on theLore.js3D WebGL engine for interactive big data rendering and theFUnproject. It facilitates the creation of interactive (2D and 3D) HTML plots of chemical data (or chemical spaces). Molecular structures are rendered usingSmilesDrawer.Associated Publication:https://academic.oup.com/bioinformatics/article/34/8/1433/4657075InstallationFaerun can be installed using pip.pipinstallfaerunIn order to use it in a script, the classFaerunhas to be imported from the package.fromfaerunimportFaerunThat’s it for the installation.Getting StartedCreate a Plot DocumentIn order to plot, a plot document has to be created. To do so, create an instance of the classFaerunfromfaerunimportFaerunf=Faerun(title='faerun-example',clear_color='#222222',coords=False,view='free')Here, we set thetitleof the plot document. This will be used as the title of the HTML document. The clear color of the canvas, which is the background color of the plot, is set to'#222222'(which is the hex-code for a dark gray).
The drawing of coordinate axes is disabled by settingcoords=Falseand since we want to draw 3D data, the argumentviewis set to'free'to enable the user to pan and rotate the plot.Preparing Data for PlottingThe next step is to prepare the data which is to be plotted. In the tutorial, we will just generate some nice looking data usingnumpy.importnumpyasnpx=np.linspace(0,12.0,326)y=np.sin(np.pi*x)z=np.cos(np.pi*x)c=np.random.randint(0,6,len(x))This data can then be wrapped in adict. In addition,DataFramefrom thepandaspackage are also supported by faerun.
In the example, the same values are used for the colorscand labelslabels.data={'x':x,'y':y,'z':z,'c':c,'labels':c}Adding a Scatter LayerGiven theFaeruninstance and the data, a scatter plot can be created using the methodadd_scatter.f.add_scatter('helix',data,shader='sphere',colormap='Dark2',point_scale=5.0,categorical=True,has_legend=True,legend_labels=[(0,'Zero'),(1,'One')])The data is added as a scatter layer named helix. The chose shader will render the data points as
spheres (with diffuse and specular lighting) of size 5.0 with colors from thematplotlibcolormap'Dark2'.
As thecis categorical, the parametercategoricalis set toTrue, otherwisematplotlibwill mess up the values.Finally,has_legend=Trueadds the scatter layer to the legend andlegend_labelsis alistoftuple, associating values with a label.Saving to HTMLThe faerun document can the be plotted to an HTML document with an accompanying JavaScript data file.f.plot('helix')This saves the plot ashelix.htmlandhelix.js. The files can be opened locally or hosted on any web server.Saving to Faerun Data FileThe faerun document can also be exported to a faerun data file, which in turn can then be hosted using thewebmodule.importpicklewithopen('helix.faerun','wb+')ashandle:pickle.dump(f.create_python_data(),handle,protocol=pickle.HIGHEST_PROTOCOL)Complete ExampleimportpickleimportnumpyasnpfromfaerunimportFaerundefmain():f=Faerun(title='faerun-example',clear_color='#222222',coords=False,view='free')x=np.linspace(0,12.0,326)y=np.sin(np.pi*x)z=np.cos(np.pi*x)c=np.random.randint(0,2,len(x))data={'x':x,'y':y,'z':z,'c':c,'labels':c}f.add_scatter('helix',data,shader='sphere',colormap='Dark2',point_scale=5.0,categorical=True,has_legend=True,legend_labels=[(0,'Zero'),(1,'One')])f.plot('helix')withopen('helix.faerun','wb+')ashandle:pickle.dump(f.create_python_data(),handle,protocol=pickle.HIGHEST_PROTOCOL)if__name__=='__main__':main()HostedIntroductionWhile small plots can easily be created and stored in a single HTML and JavaScript file, which are then loaded completely in the browsers memory, this is not possible for larger data sets due to browser limitations.
In order to solve this problem, Faerun includes a small HTTP server (based on cherrypy) to serve the data to the browser.Creating Faerun Data FilesAs shown in Getting Started, Faerun can save data as.faerundata files usingpickle.withopen('helix.faerun','wb+')ashandle:pickle.dump(f.create_python_data(),handle,protocol=pickle.HIGHEST_PROTOCOL)Starting a Faerun Web Serverfromfaerunimporthosthost('helix.faerun',label_type='default',theme='dark')Formatting LabelsLabels can be formatted by defining a customlabel_formatter. If nolabel_formatteris provided to thehostfunction, the default is used:label_formatter=lambdalabel,index,name:label.split('__')[0]This default splits the label value on'__'to store different labels and enable search on different values the the displayed labels. See “Searching” for details. Defining a custom label formatter is straight forward. As an example, let’s prefix each label with a string and add their index and layer name:defcustom_label_formatter(label,index,name):returnf'Example:{label}({index},{name})'host('helix.faerun',label_type='default',theme='dark',label_formatter=custom_label_formatter)This function is then called whenever a label is requested from the server. In addition to the argumentlabel, the argumentsindexandnamecan be used to further customize the displayed label and represent the integer index of the data point and the data layer they belong to (e.g. the name defined withadd_scatter).Adding HyperlinksFaerun allows to link the data to an arbitrary URL which can be visited upon double-clicking a data point. In order to do this, alink_formatterhas to be provided. This works similar to customizing the label.defcustom_link_formatter(label,index,name):returnf'https://www.google.com/search?q={label}'host('helix.faerun',label_type='default',theme='dark',link_formatter=custom_link_formatter)SearchingThe hosted version of a Faerun visualization also allows for searching. As a default, the search searches for exact matches in labels (substring or regex searches are not possible at this time).However, the search can be customized. As described in “Formatting Labels”, additional label values can be added by separating them using'__'.c=np.random.randint(0,2,len(x))labels=['']*len(c)fori,einenumerate(c):labels[i]=str(e)+'__'+str(i%20)data={'x':x,'y':y,'z':z,'c':c,'labels':labels}The above examples adds an additional label value and as default, the second label value is then used by the search.If there are additional label values, the search index can be set using thesearch_indexargument.Add Info / DocumentationAs the visualization is ready to be deployed to a publicly accessible web server, it might be of interest to add a documentation. Thehostmethod supports the argumentinfothat accepts a (markdown formatted) string. This information is the desplayed on the generated web page.info=('#Welcome to Fearun','This is a small Faerun example.''','Yay markdown! This means that you can easily:','- Add lists','- Build tables','- Insert images and links','- Add code examples','- ...')host('helix.faerun',label_type='default',theme='dark',label_formatter=custom_label_formatter,link_formatter=custom_link_formatter,info='\n'.join(info))An info button is then shown next to the screenshot button, which upon click opens a window containing the info.Complete ExampleimportpickleimportnumpyasnpfromfaerunimportFaerun,hostdefmain():f=Faerun(title='faerun-example',clear_color='#222222',coords=False,view='free')x=np.linspace(0,12.0,326)y=np.sin(np.pi*x)z=np.cos(np.pi*x)c=np.random.randint(0,2,len(x))labels=['']*len(c)fori,einenumerate(c):labels[i]=str(e)+'__'+str(i%20)data={'x':x,'y':y,'z':z,'c':c,'labels':labels}f.add_scatter('helix',data,shader='sphere',colormap='Dark2',point_scale=5.0,categorical=True,has_legend=True,legend_labels=[(0,'Zero'),(1,'One')])f.plot('helix')withopen('helix.faerun','wb+')ashandle:pickle.dump(f.create_python_data(),handle,protocol=pickle.HIGHEST_PROTOCOL)defcustom_label_formatter(label,index,name):returnf'Example:{label}({index},{name})'defcustom_link_formatter(label,index,name):returnf'https://www.google.com/search?q={label}'info=('#Welcome to Fearun','This is a small Faerun example.''','Yay markdown! This means that you can easily:','- Add lists','- Build tables','- Insert images and links','- Add code examples','- ...')host('helix.faerun',label_type='default',theme='dark',label_formatter=custom_label_formatter,link_formatter=custom_link_formatter,info='\n'.join(info))if__name__=='__main__':main()ExamplesDrugbank 3DDrugbank 2DFurthermore, the documentation oftmapprovides a wide range of examples of Faerun in use. Seehere.DocumentationFaerunclassfaerun.Faerun(title:str='',clear_color:str='#111111',coords:bool=True,coords_color:str='#888888',coords_box:bool=False,coords_ticks:bool=True,coords_grid:bool=False,coords_tick_count:int=10,coords_tick_length:float=2.0,coords_offset:float=5.0,x_title:str='',y_title:str='',show_legend:bool=True,legend_title:str='Legend',legend_orientation:str='vertical',legend_number_format:str='{:.2f}',view:str='free',scale:float=750.0,alpha_blending:bool=False,style:Dict[str,Dict[str,Any]]={})Creates a faerun object which is an empty plotting surface where
layers such as scatter plots can be added.Constructor for Faerun.Keyword Argumentstitle(str, optional) – The plot titleclear_color(str, optional) – The background color of the plotcoords(bool, optional) – Show the coordinate axes in the plotcoords_color(str, optional) – The color of the coordinate axescoords_box(bool, optional) – Show a box around the coordinate axescoords_tick(bool, optional) – Show ticks on coordinate axescoords_grid(bool, optional) – Extend ticks to create a gridcoords_tick_count(int, optional) – The number of ticks to display per axiscoords_tick_length(float, optional) – The length of the coordinate tickscoords_offset(float, optional) – An offset added to the coordinate axesx_title(str, optional) – The title of the x-axisy_title(str, optional) – The title of the y-axisshow_legend(bool, optional) – Whether or not to show the legendlegend_title(str, optional) – The legend titlelegend_orientation(str, optional) – The orientation of the legend (‘vertical’ or ‘horizontal’)legend_number_format(str, optional) – A format string applied to the numbers displayed in the legendview(str, optional) – The view (front, back, top, bottom, left, right, free)scale(float, optional) – To what size to scale the coordinates (which are normalized)alpha_blending(bool, optional) – Whether to activate alpha blending (required for smoothCircle shader)style(Dict[str, Dict[str, Any]], optional) – The css styles to apply to the HTML elements__init__(title:str='',clear_color:str='#111111',coords:bool=True,coords_color:str='#888888',coords_box:bool=False,coords_ticks:bool=True,coords_grid:bool=False,coords_tick_count:int=10,coords_tick_length:float=2.0,coords_offset:float=5.0,x_title:str='',y_title:str='',show_legend:bool=True,legend_title:str='Legend',legend_orientation:str='vertical',legend_number_format:str='{:.2f}',view:str='free',scale:float=750.0,alpha_blending:bool=False,style:Dict[str,Dict[str,Any]]={})Constructor for Faerun.Keyword Argumentstitle(str, optional) – The plot titleclear_color(str, optional) – The background color of the plotcoords(bool, optional) – Show the coordinate axes in the plotcoords_color(str, optional) – The color of the coordinate axescoords_box(bool, optional) – Show a box around the coordinate axescoords_tick(bool, optional) – Show ticks on coordinate axescoords_grid(bool, optional) – Extend ticks to create a gridcoords_tick_count(int, optional) – The number of ticks to display per axiscoords_tick_length(float, optional) – The length of the coordinate tickscoords_offset(float, optional) – An offset added to the coordinate axesx_title(str, optional) – The title of the x-axisy_title(str, optional) – The title of the y-axisshow_legend(bool, optional) – Whether or not to show the legendlegend_title(str, optional) – The legend titlelegend_orientation(str, optional) – The orientation of the legend (‘vertical’ or ‘horizontal’)legend_number_format(str, optional) – A format string applied to the numbers displayed in the legendview(str, optional) – The view (front, back, top, bottom, left, right, free)scale(float, optional) – To what size to scale the coordinates (which are normalized)alpha_blending(bool, optional) – Whether to activate alpha blending (required for smoothCircle shader)style(Dict[str, Dict[str, Any]], optional) – The css styles to apply to the HTML elementsadd_scatter(name:str,data:Union[dict,pandas.core.frame.DataFrame],mapping:dict={'c':'c','cs':'cs','labels':'labels','s':'s','x':'x','y':'y','z':'z'},colormap:Union[str,matplotlib.colors.Colormap]='plasma',shader:str='sphere',point_scale:float=1.0,max_point_size:float=100.0,fog_intensity:float=0.0,saturation_limit:float=0.2,categorical:bool=False,interactive:bool=True,has_legend:bool=False,legend_title:str=None,legend_labels:dict=None,min_legend_label:Union[str,float]=None,max_legend_label:Union[str,float]=None)Add a scatter layer to the plot.Parametersname(str) – The name of the layerdata(dictorDataFrame) – A Python dict or Pandas DataFrame containing the dataKeyword Argumentsmapping(dict, optional) – The keys which contain the data in the input dict or the column names in the pandasDataFramecolormap(strorColormap, optional) – The name of the colormap (can also be a matplotlib Colormap object)shader(str, optional) – The name of the shader to use for the data point visualizationpoint_scale(float, optional) – The relative size of the data pointsmax_point_size(int, optional) – The maximum size of the data points when zooming infog_intensity(float, optional) – The intensity of the distance fogsaturation_limit(float, optional) – The minimum saturation to avoid “gray soup”categorical(bool, optional) – Whether this scatter layer is categoricalinteractive(bool, optional) – Whether this scatter layer is interactivehas_legend(bool, optional) – Whether or not to draw a legendlegend_title(str, optional) – The title of the legendlegend_labels(dict, optional) – A dict mapping values to legend labelsmin_legend_label(Union[str, float], option) – The label used for the miminum value in a ranged (non-categorical) legendmax_legend_label(Union[str, float], option) – The label used for the maximum value in a ranged (non-categorical) legendadd_tree(name:str,data:Union[dict,pandas.core.frame.DataFrame],mapping:dict={'c':'c','from':'from','to':'to','x':'x','y':'y','z':'z'},color:str='#666666',colormap:Union[str,matplotlib.colors.Colormap]='plasma',fog_intensity:float=0.0,point_helper:str=None)Add a tree layer to the plot.Parametersname(str) – The name of the layerdata(dictorDataFrame) – A Python dict or Pandas DataFrame containing the dataKeyword Argumentsmapping(dict, optional) – The keys which contain the data in the input dict or DataFramecolor(str, optional) – The default color of the treecolormap(strorColormap, optional) – The name of the colormap (can also be a matplotlib Colormap object)fog_intensity(float, optional) – The intensity of the distance fogpoint_helper(str, optional) – The name of the scatter layer to associate with this tree layer (the source of the coordinates)create_data()Returns a JavaScript string defining a JavaScript object containing the data.ReturnsJavaScript code defining an object containing the dataReturn typestrcreate_python_data()Returns a Python dict containing the dataReturnsThe data defined in this Faerun instanceReturn typedictstaticdiscrete_cmap(n_colors:int,base_cmap:str)Create an N-bin discrete colormap from the specified input map.Parametersn_colors(int) – The number of discrete colors to generateKeyword Argumentsbase_cmap(str) – The colormap on which to base the discrete mapReturnsThe discrete colormapReturn typeColormapget_min_max()Get the minimum an maximum coordinates from this plotter instanceReturnsThe minimum and maximum coordinatesReturn typetuplestaticin_notebook()Checks whether the code is running in an ipython notebook.ReturnsWhether the code is running in an ipython notebookReturn typeboolplot(file_name:str='index',path:str='./',template:str='default')Plots the data to an HTML / JS file.Keyword Argumentsfile_name(str, optional) – The name of the HTML / JS filepath(str, optional) – The path to which to write the HTML / JS filetemplate(str, optional) – The name of the template to useWebfaerun.host(path:str,label_type:str='smiles',theme:str='light',title:str='Faerun',label_formatter:Callable[[str,int,str],str]=None,link_formatter:Callable[[str,int,str],str]=None,info:str=None,legend:bool=False,legend_title:str='Legend',view:str='front',search_index:int=1)Start a cherrypy server hosting a Faerun visualization.Parameterspath(str) – The path to the fearun data fileKeyword Argumentslabel_type(str) – The type of the labelstheme(str) – The theme to use in the front-endtitle(str) – The title of the HTML documentlabel_formatter(Callable[[str, int, str], str]) – A function used for formatting labelslink_formatter(Callable[[str, int, str], str]) – A function used for formatting linksinfo(str) – A string containing markdown content that is shown as an info in the visualizationlegend(bool) – Whether or not to show the legendlegend_title(str) – The title of the legendview(str) – The view type (‘front’, ‘back’, ‘top’, ‘bottom’, ‘right’, ‘left’, or ‘free’)search_index(int) – The index in the label values that is used for searchingTODOAdd the abilty to draw shapes as well as coloursMake output templatable