One Codex Notebooks – Tutorial

In this tutorial, we’ll highlight how to fetch samples and analysis results, access data from your projects, collate results across many samples from a study, get started with basic exploratory plotting, and calculate several common diversity statistics from the literature.

To follow along, log into your account and click “Copy this notebook” on the top right. You can then make edits and experiment as you work your way through the tutorial.

A few quick tips to get you started…

We’ve built a library for working with our platform more easily from Python. It’s quite simple, and you can get started quickly here with an example like the following:

from onecodex import Api
ocx = Api()  # This automatically connects to your account
public_samples = ocx.Samples.where(public=True)

sample = ocx.Samples.get('e94934526edd49f6')  # Fetch a specific sample...
sample.metadata                               # ...view its metadata...
sample.metadata.name = 'My new name!'         # ...update...
sample.metadata.save()                        # ...and save!

A few other resources you may find useful include: notes on getting started with our One Codex library; the full documentation on our API (more technical); a cheat sheet on getting started with Pandas, a Python library for data manipulation; and reading a few of our blog posts (where we use these notebooks extensively). As always, also feel free to send us questions or suggestions by clicking the chat icon in the bottom right!

Ps. We’ll include a similar header on all new notebooks as a quick getting started guide. Feel free to double click on this cell to edit and delete these tips.

1. Create a One Codex API connection

This first step connects your notebook to the One Codex API, providing secure access to your private data as well as publicly shared samples available on our platform. By convention, we recommend instantiating a connection to the API with ocx = Api().

[1]:
from onecodex import Api

ocx = Api()  # This automatically logs you into your account by
             # injecting a JWT authentication token only valid for 24 hours
             # (this notebook session)

2. Samples

Get some public samples

[2]:
samples = ocx.Samples.where(public=True, limit=10)
[3]:
samples[0]  # Printing an API resource renders an HTML table
[3]:
Samples('32cc1779ca174ea8')
created_atdatetime.datetime(2015, 2, 4, 17, 13, 27, tzinfo=datetime.timezone.utc)
error_msgNone
filename'SRR606245.fastq.gz'
metadata<Metadata 7c60f93b314c417b>
owner<Users 767b0e0da9ab4312>
primary_classification<Classifications ad953e46da6e40e5>
projectNone
size102283983
tags[<Tags dbcf5b98bca54a16: "complex">]
status'available'
visibility'public'
updated_atdatetime.datetime(2026, 3, 23, 12, 26, 44, 336174, tzinfo=datetime.timezone.utc)

Fetch a sample by filename

[4]:
# Find a public sample by filename
ocx.Samples.where(filename='EcoliAMR2.fastq.gz', public=True)
[4]:
<SampleCollection[Samples] length=1 : [<Samples 29c0503f12714d9d: "EcoliAMR2.fastq.gz">]>
[5]:
# Find a sample in *your* account by filename
# Note: you will need to replace this with the filename for a sample in your account
ocx.Samples.where(filename="placeholder")
[5]:
<SampleCollection[Samples] length=0 : []>

Find a sample by its ID

[6]:
ocx.Samples.get('29c0503f12714d9d')
[6]:
Samples('29c0503f12714d9d')
created_atdatetime.datetime(2019, 2, 14, 16, 57, 55, 360376, tzinfo=datetime.timezone.utc)
error_msgNone
filename'EcoliAMR2.fastq.gz'
metadata<Metadata b1ba508617e0478f>
owner<Users b9b18c598eb948f3>
primary_classification<Classifications 2d913c8b1f82414c>
projectNone
size29125449
tags[<Tags 6dd13b28d4024402: "E. coli">, <Tags e48c0ecd808a49ff: "isolate">]
status'available'
visibility'public'
updated_atdatetime.datetime(2025, 4, 25, 21, 39, 23, 470149, tzinfo=datetime.timezone.utc)

3. Jobs and Analyses

Each sample (FASTA/FASTQ) uploaded to One Codex is analyzed with at least one job. The current classification database is always run on each sample. Additional jobs can be run on your samples, including different job types.

An analysis can be thought of as a result of a job run on a sample.

Get an Analysis

We’re fetching a metagenomic classification result by its ID. You can also get a sample’s classification result with samples[0].primary_classification. You can find a classification’s unique ID in the URL when viewing the results page. Here, we’ll use one of our public examples.

[7]:
analysis = ocx.Classifications.get('e18dc42b4f0d427b')
[8]:
analysis
[8]:
Classifications('e18dc42b4f0d427b')
created_atdatetime.datetime(2016, 4, 18, 0, 24, 47, 469033, tzinfo=datetime.timezone.utc)
updated_atdatetime.datetime(2016, 4, 18, 0, 24, 47, 469033, tzinfo=datetime.timezone.utc)
completeTrue
error_msg''
job<Jobs One Codex Database (2017) - classification (dd71422220c3423b)>
job_args{}
sample<Samples 0ee172af60e84f61: "ERR757133.fastq.gz">
successTrue
costNone
draftFalse
dependencies[]
results_uri'https://refgenomics-userdata-production-encrypted.s3.us-east-1.amazonaws.com/user_5891ee65711c4d5e/file_0ee172af60e84f61/analysis_e18dc42b4f0d427b/results_api_data.v10.json.gz?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA6GPUEB7CHYSUN64Q%2F20261022%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20261022T202556Z&X-Amz-Expires=43200&X-Amz-SignedHeaders=host&X-Amz-Signature=187dd808c8d7785bd7e0e3c3da45b8592f544124ecdc24b44bf3de3d9e0f22ed'

View Classification Results

[9]:
# Fetches the results and returns a Pandas DataFrame
df = analysis.table()
df.head()
[9]:
tax_id parent_tax_id readcount readcount_w_children filtered_readcount filtered_readcount_w_children name rank abundance abundance_w_children
0 1 NaN 2 139143 2 139143 root no rank None None
1 131567 1 218 139140 218 139140 cellular organisms no rank None None
2 2 131567 26496 138922 26496 138922 Bacteria superkingdom None None
3 1783270 2 0 66625 0 66625 FCB group no rank None None
4 976 68336 13 66623 13 66623 Bacteroidetes phylum None None

Note: Readcounts, Readcounts w/ Children, Abundance, and Abundance w/ Children are some of the metrics we generate for classification results. You can read more here: https://docs.onecodex.com/en/articles/10245796-q-what-is-the-difference-between-readcount-readcount-with-children-and-abundances

[10]:
# Filter results to genus-level hits only
df[df['rank'] == 'genus'].head()
[10]:
tax_id parent_tax_id readcount readcount_w_children filtered_readcount filtered_readcount_w_children name rank abundance abundance_w_children
8 816 815 41773 48688 41773 48688 Bacteroides genus None None
17 29465 31977 6544 6669 6544 6669 Veillonella genus None None
22 841 186803 2517 2523 2517 2523 Roseburia genus None None
29 1573536 128827 0 1315 0 1315 Faecalicoccus genus None None
34 375288 171551 44 1123 44 1123 Parabacteroides genus None None

View details about the job

This is the strictly-versioned job run for this analysis (code, execution environment, and reference database). Note also the job’s analysis_type here, which is 'classification'–meaning that it produces taxonomic classifications for a sample. Other jobs can produce other types of results.

[11]:
analysis.job
[11]:
Jobs('dd71422220c3423b')
created_atdatetime.datetime(2016, 4, 15, 23, 23, 10, 511330, tzinfo=datetime.timezone.utc)
name'One Codex Database (2017)'
job_args_schema{}
analysis_type'classification'
publicTrue
job_typeNone
draftFalse

Find jobs by type

You can find jobs based on their analysis_type. These include: classification, panel, alignment, control, report, functional, mlst, and workflow.

[12]:
# For example, this is one of the user-runnable marker panels you can now find under
# the Run Workflows page -- an AMR panel:
ocx.Jobs.where(public=True, analysis_type='panel')[0]
[12]:
Jobs('ffe9ee7caa054eb7')
created_atdatetime.datetime(2016, 5, 26, 22, 39, 30, 72435, tzinfo=datetime.timezone.utc)
name'E. coli AMR'
job_args_schema{'unevaluatedProperties': False}
analysis_type'panel'
publicTrue
job_typeNone
draftFalse

4. Fetching samples from a project

Projects offer a useful mechanism for sharing and organizing your samples. In this tutorial, we’re going to work with a public project consisting of data from the Sequence Read Archive (SRA). Since this data is public, the following example code should work from any account.

[13]:
# Fetch a project by its ID.
#
# You can also fetch your own projects by the `name` field using a `.where()`
# query. For example:
#
# ocx.Projects.where(name="Infant Gut Microbiome, Karelia (All)")
#
# Alternatively, you can fetch a public project using its short `project_name`
# and by passing `public=True`. For example:
#
# ocx.Projects.where(public=True, project_name='prjna290380')
#

project = ocx.Projects.get('d53ad03b010542e3')

Vatanen T, Kostic AD, d’Hennezel E, et al. Variation in Microbiome LPS Immunogenicity Contributes to Autoimmunity in Humans Cell. 2016 May 5;165(4):842-53.

Tip: You can inspect objects by simply entering them as a standalone notebook cell. Most objects should render as nice HTML tables displaying all their key properties.

[14]:
project
[14]:
Projects('d53ad03b010542e3')
description('A longitudinal analysis of the developing gut microbiome in infants from ' 'Finland, Estonia, and Russian Karelia')
external_idNone
name'Infant Gut Microbiome, Karelia (All)'
owner<Users 7189f36afe3640ac>
permissions['can_see_files']
project_name'prjna290380'
publicTrue

Fetch this project’s samples

[15]:
# This returns 0 samples because by default ocx.Samples.where
# searches samples in your account only
len(ocx.Samples.where(project=project.id))
[15]:
0
[16]:
# So, we need to pass the `public=True` flag to ocx.Samples.where() in order to
# search all public samples. Here, we limit this to return 50 samples. By default,
# queries return all private samples or up to 1000 public samples. Pass `limit=n`
# to retrieve up to `n` available public samples.
samples = ocx.Samples.where(project=project.id, public=True, limit=50)
[17]:
len(samples)
[17]:
50

Now, let’s analyze the results for the samples in this project

Note: These samples have a lot of custom metadata. You can add custom metadata to your samples on our website, by uploading an Excel sample sheet, or via our API. For more details, see our documentation on metadata: https://docs.onecodex.com/docs/metadata.

[18]:
# take a peek at what metadata is available for these samples:
samples[0].metadata
[18]:
Metadata('6b69295478de4f1f')
custom{'abx_first_year': True, 'after_abx': False, 'age_at_collection': 1093, 'allergy_birch': True, 'allergy_cat': True, 'allergy_dog': True, 'allergy_dustmite': False, 'allergy_egg': True, 'allergy_milk': False, 'allergy_peanut': False, 'allergy_timothy': False, 'any_baby_formula': False, 'barley': False, 'bf_length': 14, 'bio_sample_model': 'MIGS/MIMS/MIMARKS.human-gut', 'bioproject_id': 'PRJNA290380', 'breast_feeding_end': True, 'cereal': False, 'collection_month': 36, 'corn': True, 'country': 'FIN', 'delivery': 'vaginal', 'eggs': True, 'env_biome': 'ENVO:2100002', 'env_feature': 'ENVO:00000062', 'env_material': 'ENVO:00002003', 'exclusive_breast_feeding': True, 'fish': True, 'fruits_and_berries': True, 'gender': 'Male', 'geo_loc_name': 'Finland:Espoo', 'gest_time': 286, 'hla_risk_class': 2, 'host': 'Homo sapiens', 'host_age': 1093, 'host_subject_id': 'E018421', 'hydrosylated_formula': False, 'instrument_model': 'Illumina HiSeq 2500', 'library_layout': 'PAIRED', 'library_name': 'G80420', 'library_selection': 'RANDOM', 'library_source': 'METAGENOMIC', 'library_strategy': 'WGS', 'meat': True, 'milk': False, 'num_aabs': 0, 'num_abx_first_year': 2, 'num_abx_treatments': 5, 'num_preceeding_abx': 5, 'oat': True, 'other_food': True, 'other_grains': False, 'other_than_bf': True, 'partly_hydrosylated_formula': False, 'ref_biomaterial': 'PMID:27259157', 'regular_formula': False, 'rice': True, 'root_vegetables': True, 'rye': True, 'sampleid': 3109913, 'seroconverted': False, 'soy': True, 'sra_name': 'G80420', 'sra_run_id': 'SRR4408293', 'sra_sample_id': 'SAMN05827084', 'study_id': 'SRP090628', 'study_title': 'A longitudinal analysis of the developing gut microbiome in ' 'infants from Finland, Estonia, and Russian Karelia', 'subjectid': 'E018421', 'totalige': 62.9, 'totalige_high': False, 'totalige_log': 1.798650645, 'unnamed_0': 1047, 'vegetables': True, 'wheat': True}
date_collectedNone
date_sequencedNone
description('Submitted by Broad Institute as sample SUB2008451. Link: ' 'https://trace.ncbi.nlm.nih.gov/Traces/sra/?run=SRR4408293')
external_sample_id'SRR4408293'
library_type'WGS'
location_latNone
location_lonNone
location_stringNone
nameNone
platform'Illumina HiSeq'
sample_type'Metagenomic'
sampleSamples('0b2d0b5397324841')
starredFalse
updated_atdatetime.datetime(2017, 8, 22, 0, 29, 59, 633018, tzinfo=TzInfo(0))
[19]:
# To keep things speedy, we're going to work with a subset of the samples from this project
ten_samples = samples[:10]

5. Heatmaps

Our library includes support for plotting heatmaps. By default, heatmaps display the top 10 taxa, but this can be changed by passing top_n=. Alternatively, pass threshold=cutoff to display only taxa above a certain abundance threshold, or use a combination of both threshold and top_n. Pass, e.g., rank='genus' to restrict the analysis to a specific taxonomic rank. You can customize the plot using title=. In addition, specify xlabel= or ylabel= to label the axes.

[20]:
ten_samples.plot_heatmap(
    metric="abundance_w_children",
    rank='genus', # try changing the rank to species
    title='Top 20 Genera',
    top_n=20
)

6. Stacked Bar Plots

Bar plots are a common way to view taxonomic abundance data

[21]:
ten_samples.plot_bargraph(
    rank='genus',
    legend='Genus',
    ylabel='Relative Abundance',
    top_n=25
)

Barplot: single sample

Here, we’re going to filter the samples to a single subject of the study and generate a stacked bar plot.

[22]:
# filter to samples from subject P014839
subject_samples = samples.filter(lambda s: s.metadata.custom["host_subject_id"] == "P014839")

# note: subject_samples is a collection containing a single sample
subject_samples.plot_bargraph(
    rank="genus",
    metric="normalized_readcount_w_children",
    label="host_age",
    title="Subject P014839",
    xlabel="Host Age at Sampling Time (days)",
    ylabel="Relative Abundance",
    legend="Genus",
)

7. Alpha diversity statistics

The onecodex Python client library provides rich access to the API layer of the One Codex platform. This includes several built-in functions for computing common alpha and beta diversity statistics. More statistics can be calculated by passing data from One Codex to the `skbio <https://scikit.bio/>`__ library (the basis for much of QIIME2).

First, we’ll get started by computing Simpson’s index for our subset of ten samples.

[23]:
ten_samples.alpha_diversity(diversity_metric='simpson')
[23]:
simpson
classification_id
001b3ea2093b426d 0.898043
850ba22531cd4cde 0.899343
db177a540a1c43b0 0.832201
d281a52b08f54b6a 0.868964
a0cc5e58e2074fab 0.900434
4b3aa0d6eabb48dc 0.822121
d0238007374a4dab 0.827712
8abf53a2cf4341fe 0.849236
8599190018b045c8 0.848296
11ded36641bf4be2 0.569782

Several other alpha (within-sample) diversity statistics are also included, e.g., Shannon’s diversity index. The results are returned as a pandas DataFrame, which can be manipulated to include sample names or other metadata.

Note: Shannon diversity is calculated using log base e (natural log).

[24]:
shannon = ten_samples.alpha_diversity(diversity_metric='shannon')
shannon['filename'] = [s.filename for s in ten_samples]
shannon['host_age_years'] = ten_samples.metadata['host_age'][shannon.index] / 365
shannon
[24]:
shannon filename host_age_years
classification_id
001b3ea2093b426d 2.958068 SRR4408293.fastq 2.994521
850ba22531cd4cde 2.877836 SRR4305031.fastq 1.879452
db177a540a1c43b0 2.519541 SRR4408292.fastq 1.843836
d281a52b08f54b6a 2.514536 SRR4305032.fastq 0.473973
a0cc5e58e2074fab 3.090198 SRR4305033.fastq 1.350685
4b3aa0d6eabb48dc 2.384505 SRR4305034.fastq 0.627397
d0238007374a4dab 2.590478 SRR4305035.fastq 1.375342
8abf53a2cf4341fe 2.390861 SRR4305036.fastq 1.068493
8599190018b045c8 2.901986 SRR4305037.fastq 1.169863
11ded36641bf4be2 1.904235 SRR4305038.fastq 1.608219

8. Beta diversity statistics

Next, we’ll explore a range of built-in beta diversity statistics. Most of these functions directly return a skbio distance matrix object.

[25]:
distance_matrix = ten_samples.beta_diversity(diversity_metric='braycurtis')
[26]:
# Printing shows the distance matrix. Here, the labels are classification IDs.
distance_matrix.to_data_frame()
[26]:
001b3ea2093b426d 850ba22531cd4cde db177a540a1c43b0 d281a52b08f54b6a a0cc5e58e2074fab 4b3aa0d6eabb48dc d0238007374a4dab 8abf53a2cf4341fe 8599190018b045c8 11ded36641bf4be2
001b3ea2093b426d 0.000000 0.926267 0.870811 0.964621 0.905271 0.983620 0.959864 0.957985 0.865977 0.904567
850ba22531cd4cde 0.926267 0.000000 0.834032 0.819205 0.876406 0.721971 0.915060 0.930346 0.573122 0.942613
db177a540a1c43b0 0.870811 0.834032 0.000000 0.953032 0.900686 0.971620 0.791720 0.791256 0.819967 0.888104
d281a52b08f54b6a 0.964621 0.819205 0.953032 0.000000 0.924544 0.801560 0.890492 0.952330 0.930428 0.978791
a0cc5e58e2074fab 0.905271 0.876406 0.900686 0.924544 0.000000 0.608457 0.939912 0.750836 0.909499 0.898938
4b3aa0d6eabb48dc 0.983620 0.721971 0.971620 0.801560 0.608457 0.000000 0.886998 0.768938 0.953099 0.987432
d0238007374a4dab 0.959864 0.915060 0.791720 0.890492 0.939912 0.886998 0.000000 0.739914 0.909648 0.952105
8abf53a2cf4341fe 0.957985 0.930346 0.791256 0.952330 0.750836 0.768938 0.739914 0.000000 0.968172 0.948821
8599190018b045c8 0.865977 0.573122 0.819967 0.930428 0.909499 0.953099 0.909648 0.968172 0.000000 0.904535
11ded36641bf4be2 0.904567 0.942613 0.888104 0.978791 0.898938 0.987432 0.952105 0.948821 0.904535 0.000000

Note: Alternatively, we can use the built-in plot_distance function to visualize a distance matrix. The title of these plots can be set by passing the title= keyword argument.

[27]:
samples[:20].plot_distance(
    title='Bray Curtis Distance Matrix',
    # try some other diversity_metrics like `weighted_unifrac`
    diversity_metric='braycurtis'
)

By the way: You can always call help() on any of the functions in our library for a detailed description of what they do, and a few examples!

[28]:
help(samples.plot_distance)
Help on method plot_distance in module onecodex.viz._distance:

plot_distance(rank: 'Union[Rank, str]' = auto, metric: 'Union[Metric, str]' = auto, diversity_metric: 'BetaDiversityMetric' = braycurtis, title=None, xlabel=None, ylabel=None, tooltip=None, return_chart=False, linkage=average, label=None, width=None, height=None, match_taxonomy=True) method of onecodex.models.collection.SampleCollection instance
    Plot beta diversity distance matrix as a heatmap and dendrogram.

    Parameters
    ----------
    rank : :class:`~onecodex.lib.enums.Rank`, optional
        Analysis will be restricted to abundances of taxa at the specified level.
        See :class:`~onecodex.lib.enums.Rank` for details.
    metric : :class:`~onecodex.lib.enums.Metric`, optional
        The taxonomic abundance metric to use. See :class:`~onecodex.lib.enums.Metric`
        for definitions.
    diversity_metric : :class:`~onecodex.lib.enums.BetaDiversityMetric`
        Function to use when calculating the distance between two samples.
        Note that 'cityblock' and 'manhattan' are equivalent metrics.
    linkage :  :class:`~onecodex.lib.enums.Linkage`
        The type of linkage to use when clustering axes.
    title : `string`, optional
        Text label at the top of the plot.
    xlabel : `string`, optional
        Text label along the horizontal axis.
    ylabel : `string`, optional
        Text label along the vertical axis.
    tooltip : `string` or `list`, optional
        A string or list containing strings representing metadata fields. When a point in the
        plot is hovered over, the value of the metadata associated with that sample will be
        displayed in a modal.
    label : `string` or `callable`, optional
        A metadata field (or function) used to label each analysis. If passing a function, a
        dict containing the metadata for each analysis is passed as the first and only
        positional argument. The callable function must return a string.
    match_taxonomy : `bool`, default=True
        Whether or not to consider taxonomic names when looking for metadata fields mapped to
        plot attributes such as `tooltip`

    Examples
    --------
    Plot the weighted UniFrac distance between all our samples, using counts at the genus level.

    >>> samples.plot_distance(rank='genus', metric='unifrac')

9. Ordination

Our library supports ordination via Principal Component Analysis (PCA) and multidimensional scaling (MDS, more commonly known as PCoA). Ordination is useful for exploring the similarity of large numbers of samples in a single plot. Points on these plots can be colored and/or sized by taxon abundance and metadata.

These plots are fully interactive–try zooming in on specific regions, or hovering over points to see the abundance of Firmicutes taxa in each sample!

[29]:
samples.plot_pca(color='geo_loc_name', size='Bacteroides', tooltip='Firmicutes')
2026-10-22 20:33:09,229 WARNING: SampleCollection contains multiple analysis types: One Codex Database (2020), One Codex Database (2017)
[30]:
# Specifying method='pcoa' uses classic PCoA via eigenvector decomposition
samples.plot_mds(
    diversity_metric='weighted_unifrac',
    method='pcoa',
    color='host_age',
    size='Bacteroides',
    tooltip='Firmicutes'
)

10. Plotting by metadata

Our library can generate quick exploratory plots with arbitrary metadata, using both built-in and custom fields. Specify the data to plot on the horizontal or vertical axes using haxis and vaxis, respectively. The vertical axis can be numerical metadata fields, taxon IDs or names (at any rank), or a diversity statistic. The horizontal axis can be one or more categorical metadata fields.

[31]:
cat = samples.plot_metadata(vaxis='Bacteroides', haxis='allergy_cat', return_chart=True)
dog = samples.plot_metadata(vaxis='Bacteroides', haxis='allergy_dog', return_chart=True)
birch = samples.plot_metadata(vaxis='Bacteroides', haxis='allergy_birch', return_chart=True)

# Use `return_chart=True` and display multiple plots side-by-side
cat | dog | birch
[31]:
[32]:
catdog = samples.plot_metadata(
    vaxis='Bacteroidetes', haxis=('allergy_cat', 'allergy_dog'), return_chart=True
)
totalige = samples.plot_metadata(
    vaxis='totalige', haxis='Bacteroides', return_chart=True, ylabel='Total IgE'
)

catdog | totalige
[32]:

Here, we display observed taxa, Simpson’s Index, and Shannon Entropy side-by-side, grouped by the region of birth.

[33]:
observed_taxa = samples.plot_metadata(vaxis="observed_taxa", haxis="geo_loc_name", return_chart=True)
simpson = samples.plot_metadata(vaxis="simpson", haxis="geo_loc_name", return_chart=True)
shannon = samples.plot_metadata(vaxis="shannon", haxis="geo_loc_name", return_chart=True)

observed_taxa | simpson | shannon
[33]:
[34]:
cat_simpson = samples.plot_metadata(
    haxis='host_age', vaxis='simpson',
    title="Simpson's Index by Host Age",
    xlabel='Host Age', ylabel="Simpson's Index", return_chart=True
)
delivery_simpson = samples.plot_metadata(
    haxis='delivery', vaxis='simpson',
    title="Simpson's Index by Delivery Method",
    xlabel='Delivery Method', ylabel="Simpson's Index", return_chart=True
)

cat_simpson | delivery_simpson
[34]:

The plot_metadata function can search through all taxa in your samples and pull out read counts or relative abundances. Here, we look at how the abundance of Bacteroides changes with host age.

[35]:
samples.plot_metadata(haxis="host_age", vaxis="Bacteroides", plot_type="scatter")

11. Advanced manipulation of results

Results from our platform can easily be accessed as pandas DataFrames. This makes it easy to perform any sort of manipulation you choose on the raw data. In the following example, we transform the data by grabbing results at the genus level, adding a pseudocount of 1, normalizing to 1.0, and taking the fourth root.

[36]:
# Grab genus-level results and don't remove taxa with zero reads
results = ten_samples.to_df(remove_zeros=False, rank='genus')
# Add a pseudocount of 1
results = results + 1
# Normalize to 1.0 in each sample
results = results.div(results.sum(axis=1), axis=0)
# Take the fourth root
results = results ** 0.25

results.head()
[36]:
tax_id 816 191 239759 1263 216851 841 1730 33042 1678 375288 ... 13289 1068 204456 35798 1827195 54066 1187078 68288 117999 1912923
classification_id
001b3ea2093b426d 0.188932 0.187518 0.180314 0.182118 0.179380 0.178993 0.178975 0.178843 0.178566 0.180135 ... 0.177697 0.177697 0.177697 0.177697 0.177697 0.177697 0.177697 0.177697 0.177697 0.177697
850ba22531cd4cde 0.179189 0.177697 0.177697 0.177799 0.177778 0.177860 0.178258 0.177707 0.178850 0.177966 ... 0.177697 0.177697 0.177697 0.177697 0.177697 0.177697 0.177697 0.177697 0.177697 0.177697
db177a540a1c43b0 0.189947 0.177712 0.178608 0.177744 0.177712 0.179803 0.178688 0.177712 0.178213 0.179438 ... 0.177712 0.177712 0.177712 0.177712 0.177712 0.177712 0.177712 0.177712 0.177712 0.177712
d281a52b08f54b6a 0.177703 0.177697 0.177697 0.178779 0.177697 0.188071 0.177718 0.177697 0.187693 0.177697 ... 0.177697 0.177697 0.177697 0.177697 0.177697 0.177697 0.177697 0.177697 0.177697 0.177697
a0cc5e58e2074fab 0.182028 0.177696 0.177884 0.178151 0.178619 0.177924 0.179979 0.177700 0.193492 0.177696 ... 0.177696 0.177696 0.177696 0.177696 0.177696 0.177696 0.177696 0.177696 0.177696 0.177696

5 rows × 1002 columns

That’s it! Please get in touch at support@onecodex.com if you have more questions or chat with us by opening the window on the bottom right. Thanks!