Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Add Emperor class #281

Merged
merged 6 commits into from
Jul 28, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Emperor 0.9.3-dev (changes since Emperor 0.9.2 go here)
* Add toggle visible button (`Invert Selected`) under the `Visibility` tab, this button will change hidden categories to visible and vice-versa.
* Supports both NumPy 1.7 and 1.8.
* Depends on scikit-bio-dev.
* Emperor provides a Python object that is IPython aware (emperor.Emperor) that will display a usable plot from within the IPython notebook.

*Bug Fixes*

Expand Down
4 changes: 3 additions & 1 deletion emperor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@
__email__ = "antgonza@gmail.com"
__status__ = "Development"

__all__ = ['biplots', 'format', 'filter', 'sort', 'util']
from emperor.core import Emperor

__all__ = ['Emperor', 'biplots', 'format', 'filter', 'sort', 'util']
143 changes: 143 additions & 0 deletions emperor/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
r"""
Emperor 3D PCoA viewer
======================
This module provides an Object to interact and visualize an Emperor plot
from the IPython notebook.
Classes
-------
.. autosummary::
Emperor
"""
from __future__ import division

from emperor.format import (format_mapping_file_to_js, format_pcoa_to_js,
format_taxa_to_js, format_vectors_to_js,
format_comparison_bars_to_js,
EMPEROR_HEADER_HTML_STRING,
format_emperor_html_footer_string)

# we are going to use this remote location to load external resources
RESOURCES_URL = 'http://emperor.colorado.edu/master/make_emperor/emperor_outpu\
t/emperor_required_resources'

__author__ = "Yoshiki Vazquez Baeza"
__copyright__ = "Copyright 2013, The Emperor Project"
__credits__ = ["Yoshiki Vazquez Baeza"]
__license__ = "BSD"
__version__ = "0.9.3-dev"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not 1.0-dev?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not there yet, though I suspect that we'll get there in the next release (but shhhhhh, it is supposed to be a surprise 🙊 ).

__maintainer__ = "Yoshiki Vazquez Baeza"
__email__ = "yoshiki89@gmail.com"
__status__ = "Development"

class Emperor(object):
"""Display principal coordinates analysis plots
Use this object to interactively display a PCoA plot using the Emperor
GUI. IPython provides a rich display system that will let you display a
plot inline, without the need of creating a temprorary file or having to
write to disk.
Parameters
----------
ordination: skbio.maths.stats.ordination.OrdinationResults
Object containing the computed values for an ordination method in
scikit-bio.
mapping_file_data: list of list objects
Metadata mapping file used to color the plot.
mapping_file_headers: list of str objects
List of strings representing the header names of the
`mapping_file_data`. All names should be unique.
Examples
--------
Create an Emperor object and display it from the IPython notebook:
>>> data = [['PC.354', 'Control', '20061218', 'Control_mouse_I.D._354'],
... ['PC.355', 'Control', '20061218', 'Control_mouse_I.D._355'],
... ['PC.356', 'Control', '20061126', 'Control_mouse_I.D._356'],
... ['PC.481', 'Control', '20070314', 'Control_mouse_I.D._481'],
... ['PC.593', 'Control', '20071210', 'Control_mouse_I.D._593'],
... ['PC.607', 'Fast', '20071112', 'Fasting_mouse_I.D._607'],
... ['PC.634', 'Fast', '20080116', 'Fasting_mouse_I.D._634'],
... ['PC.635', 'Fast', '20080116', 'Fasting_mouse_I.D._635'],
... ['PC.636', 'Fast', '20080116', 'Fasting_mouse_I.D._636']]
>>> headers = ['SampleID', 'Treatment', 'DOB', 'Description']
>>> ordination = OrdinationResults.from_file('unweighted_unifrac_pc.txt')
Now import the Emperor object and display it using IPython, note that this
call will have no effect under an interactive Python session:
>>> from emperor import Emperor
>>> Emperor(ordination, data, headers)
Notes
-----
This object currently does not support the full range of actions that the
GUI does support and should be considered experimental at the moment.
References
----------
.. [1] EMPeror: a tool for visualizing high-throughput microbial community
data Vazquez-Baeza Y, Pirrung M, Gonzalez A, Knight R. Gigascience. 2013
Nov 26;2(1):16.
"""
def __init__(self, ordination, mapping_file_data, mapping_file_headers):
self.ordination = ordination
self.mapping_file_data = mapping_file_data
self.mapping_file_headers = mapping_file_headers
self.ids = [s[0] for s in mapping_file_data]
self._html = None

def __str__(self):
if self._html is None:
self._make_emperor()
return self._html

def _repr_html_(self):
"""Used to be displayed in the IPython notebook"""

# we import here as IPython shouldn't be a dependency of Emperor
# however if this method is called it will be from an IPython notebook
# otherwise the developer is responsible for calling this method
from IPython.display import display, HTML

# this provides a string representation that's independent of the
# filesystem, it will instead retrieve them from the official website
output = str(self).replace('emperor_required_resources',
RESOURCES_URL)

# thanks to the IPython devs for helping me figure this one out
return display(HTML(output), metadata=dict(isolated=True))

def _make_emperor(self):
"""Private method to build an Emperor HTML string"""
pcoa_string = format_pcoa_to_js(self.ids,
self.ordination.site,
self.ordination.eigvals,
self.ordination.proportion_explained)

# we pass the mapping file headers twice so nothing is filtered out
mf_string = format_mapping_file_to_js(self.mapping_file_data,
self.mapping_file_headers,
self.mapping_file_headers)

# A lot of this is going to be empty because we don't really need any
# of it
footer = format_emperor_html_footer_string(False, False, False, False)
taxa = format_taxa_to_js([], [], [])
bars = format_comparison_bars_to_js([], [], 0)
vectors = format_vectors_to_js([], [], [], [], None)

# build the HTML string
output = [EMPEROR_HEADER_HTML_STRING, mf_string, pcoa_string, taxa,
bars, vectors, footer]

# add the remote resources
_emperor = '\n'.join(output)

self._html = _emperor

Loading