{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Using Qurro with Arbitrary Compositional Data\n", "\n", "Although Qurro was initially designed for use with microbiome sequencing data, it can totally be used on any sort of compositional data. The main challenge is just getting your data formatted properly.\n", "\n", "We're going to demonstrate this by creating a Qurro visualization from \"color composition data for 22 abstract paintings.\" These data were taken from Table 1 of [Aitchison and Greenacre (2002)](https://rss.onlinelibrary.wiley.com/doi/full/10.1111/1467-9876.00275).\n", "\n", "## Requirements\n", "\n", "This notebook relies on [Qurro](https://github.com/biocore/qurro) and [seaborn](https://seaborn.pydata.org/) being installed." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 0. Setting up\n", "\n", "In this section, we replace the output directory with an empty directory. This just lets us run this notebook multiple times, without any tools complaining about overwriting files." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2022-07-05T21:46:14.148850Z", "iopub.status.busy": "2022-07-05T21:46:14.147867Z", "iopub.status.idle": "2022-07-05T21:46:15.345873Z", "shell.execute_reply": "2022-07-05T21:46:15.343311Z" } }, "outputs": [], "source": [ "# Clear the output directory so we can write these files there\n", "!rm -rf output\n", "# Since git doesn't keep track of empty directories, create the output/ directory if it doesn't already exist\n", "# (if it does already exist, -p ensures that an error won't be thrown)\n", "!mkdir -p output" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. Getting the input data ready\n", "\n", "At minimum, three files are needed to generate a Qurro visualization. This section goes into detail on each of these three files, and what they look like for the color composition data.\n", "\n", "### 1.1. Feature Table\n", "This is a table of abundance data detailing the frequencies of _features_ in _samples_. Qurro expects this table to be in the [BIOM format](http://biom-format.org/), but fortunately converting TSV files to BIOM [isn't too bad](http://biom-format.org/documentation/biom_conversion.html).\n", "\n", "#### 1.1.1. Wait, hold on, what do you mean by \"features\" and \"samples\"?\n", "In the color composition data, we consider each of the 22 paintings as a *sample*, and each color (e.g. `Red`) as a *feature*.\n", "\n", "#### 1.1.2. Viewing the example file\n", "We've provided a TSV file **`input/color-table.tsv`** containing the color composition data for the 22 paintings. Notice how the columns are samples, and the rows are features." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2022-07-05T21:46:15.354818Z", "iopub.status.busy": "2022-07-05T21:46:15.354129Z", "iopub.status.idle": "2022-07-05T21:46:15.750792Z", "shell.execute_reply": "2022-07-05T21:46:15.750251Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
12345678910...13141516171819202122
FeatureID
Black0.1250.1430.1470.1640.1970.1570.1530.1150.1780.164...0.1550.1260.1990.1630.1360.1840.1690.1460.2000.135
White0.2430.2240.2310.2090.1510.2560.2320.2490.1670.183...0.2510.2730.1700.1960.1850.1520.2070.2400.1720.225
Blue0.1530.1110.0580.1200.1320.0720.1010.1760.0480.158...0.0910.0450.0800.1070.1620.1100.1110.1410.0590.217
Red0.0310.0510.1290.0470.0330.1160.0620.0250.1430.027...0.0850.1560.0760.0540.0200.0390.0570.0380.1200.019
Yellow0.1810.1590.1330.1780.1880.1530.1700.1760.1180.186...0.1610.1310.1580.1440.1930.1650.1560.1840.1360.187
\n", "

5 rows × 22 columns

\n", "
" ], "text/plain": [ " 1 2 3 4 5 6 7 8 9 \\\n", "FeatureID \n", "Black 0.125 0.143 0.147 0.164 0.197 0.157 0.153 0.115 0.178 \n", "White 0.243 0.224 0.231 0.209 0.151 0.256 0.232 0.249 0.167 \n", "Blue 0.153 0.111 0.058 0.120 0.132 0.072 0.101 0.176 0.048 \n", "Red 0.031 0.051 0.129 0.047 0.033 0.116 0.062 0.025 0.143 \n", "Yellow 0.181 0.159 0.133 0.178 0.188 0.153 0.170 0.176 0.118 \n", "\n", " 10 ... 13 14 15 16 17 18 19 20 \\\n", "FeatureID ... \n", "Black 0.164 ... 0.155 0.126 0.199 0.163 0.136 0.184 0.169 0.146 \n", "White 0.183 ... 0.251 0.273 0.170 0.196 0.185 0.152 0.207 0.240 \n", "Blue 0.158 ... 0.091 0.045 0.080 0.107 0.162 0.110 0.111 0.141 \n", "Red 0.027 ... 0.085 0.156 0.076 0.054 0.020 0.039 0.057 0.038 \n", "Yellow 0.186 ... 0.161 0.131 0.158 0.144 0.193 0.165 0.156 0.184 \n", "\n", " 21 22 \n", "FeatureID \n", "Black 0.200 0.135 \n", "White 0.172 0.225 \n", "Blue 0.059 0.217 \n", "Red 0.120 0.019 \n", "Yellow 0.136 0.187 \n", "\n", "[5 rows x 22 columns]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from qurro._metadata_utils import read_metadata_file\n", "table = read_metadata_file(\"input/color-table.tsv\")\n", "table.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1.1.3. Converting from TSV to BIOM\n", "We need to convert this TSV file to a BIOM file that can be used with Qurro:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/home/marcus/.npm-global/bin /home/marcus/Dropbox/dotfiles/cmds /home/marcus/.npm-global/bin /home/marcus/Dropbox/dotfiles/cmds /home/marcus/.npm-global/bin /home/marcus/anaconda3/bin /home/marcus/anaconda3/condabin /home/marcus/Dropbox/dotfiles/cmds /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /snap/bin /home/marcus/anaconda3/envs/q2-2022.2-unfucked/bin\r\n" ] } ], "source": [ "!echo $PATH" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2022-07-05T21:46:15.753021Z", "iopub.status.busy": "2022-07-05T21:46:15.752869Z", "iopub.status.idle": "2022-07-05T21:46:16.335861Z", "shell.execute_reply": "2022-07-05T21:46:16.333833Z" } }, "outputs": [], "source": [ "!biom convert \\\n", " -i input/color-table.tsv \\\n", " --to-json \\\n", " -o output/color-table.biom" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1.1.4. Summarizing the newly created BIOM file\n", "The ` | head -4` thing below just means \"only show the first four lines of the output summary.\"" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2022-07-05T21:46:16.345322Z", "iopub.status.busy": "2022-07-05T21:46:16.343469Z", "iopub.status.idle": "2022-07-05T21:46:16.919444Z", "shell.execute_reply": "2022-07-05T21:46:16.917542Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Num samples: 22\r\n", "Num observations: 6\r\n", "Total count: 21\r\n", "Table density (fraction of non-zero values): 1.000\r\n" ] } ], "source": [ "!biom summarize-table -i output/color-table.biom | head -4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.2. Sample Metadata\n", "\n", "This is a file containing descriptive information about samples, where each sample has a row in the file and each sample metadata field has a column in the file. Qurro expects this to be a [TSV file](https://en.wikipedia.org/wiki/Tab-separated_values).\n", "\n", "#### 1.2.1. What sort of \"metadata\" do we have for the color composition data?\n", "We don't have much, honestly. Just from Table 1 in [Aitchison and Greenacre (2002)](https://rss.onlinelibrary.wiley.com/doi/full/10.1111/1467-9876.00275), all we really know about a given painting is its color composition.\n", "\n", "For illustrative purposes (we need _some_ sort of sample metadata to run Qurro), we've added `proportion_blue`, `proportion_black`, etc. columns to the sample metadata, as well as a `data_source` column which is just `AitchisonGreenacre2002` for all samples. These columns are obviously a bit silly; if we were super interested in studying _why_ certain paintings seem different, you could imagine us taking the time to investigate and then adding in more useful metadata columns like `artist`, `date painted`, `canvas height`, etc.\n", "\n", "#### 1.2.2. Viewing the example file\n", "We've provided an example TSV file, **`input/color-sample-metadata.tsv`**, containing the sample metadata for the color composition data. This file is suitable as-is for use in Qurro as sample metadata.\n" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "execution": { "iopub.execute_input": "2022-07-05T21:46:16.927027Z", "iopub.status.busy": "2022-07-05T21:46:16.926512Z", "iopub.status.idle": "2022-07-05T21:46:16.967815Z", "shell.execute_reply": "2022-07-05T21:46:16.967201Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
proportion_blackproportion_whiteproportion_blueproportion_redproportion_yellowproportion_otherdata_source
SampleID
10.1250.2430.1530.0310.1810.266AitchisonGreenacre2002
20.1430.2240.1110.0510.1590.313AitchisonGreenacre2002
30.1470.2310.0580.1290.1330.303AitchisonGreenacre2002
40.1640.2090.1200.0470.1780.282AitchisonGreenacre2002
50.1970.1510.1320.0330.1880.299AitchisonGreenacre2002
\n", "
" ], "text/plain": [ " proportion_black proportion_white proportion_blue proportion_red \\\n", "SampleID \n", "1 0.125 0.243 0.153 0.031 \n", "2 0.143 0.224 0.111 0.051 \n", "3 0.147 0.231 0.058 0.129 \n", "4 0.164 0.209 0.120 0.047 \n", "5 0.197 0.151 0.132 0.033 \n", "\n", " proportion_yellow proportion_other data_source \n", "SampleID \n", "1 0.181 0.266 AitchisonGreenacre2002 \n", "2 0.159 0.313 AitchisonGreenacre2002 \n", "3 0.133 0.303 AitchisonGreenacre2002 \n", "4 0.178 0.282 AitchisonGreenacre2002 \n", "5 0.188 0.299 AitchisonGreenacre2002 " ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "metadata = read_metadata_file(\"input/color-sample-metadata.tsv\")\n", "metadata.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.3. Feature Rankings\n", "\n", "By \"feature rankings,\" we usually mean either the feature loadings in a biplot or \"differentials.\" Please see Qurro's paper ([preprint here](https://www.biorxiv.org/content/10.1101/2019.12.17.880047v1)) for more details on what these terms mean.\n", "\n", "In the next section we're going to generate a biplot for the color composition abundance data using Aitchison PCA, and use the feature loadings in that biplot as the feature rankings." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. Generating and visualizing a compositional biplot\n", "\n", "We generate the biplot using Aitchison PCA, wherein we take the [singular value decomposition](https://en.wikipedia.org/wiki/Singular_value_decomposition) of the [center log-ratio transform](https://en.wikipedia.org/wiki/Compositional_data#Center_logratio_transform) of the feature table.\n", "\n", "As you can see, this looks pretty similar to the biplot figures of this data shown in [Aitchison and Greenacre (2002)](https://rss.onlinelibrary.wiley.com/doi/full/10.1111/1467-9876.00275). Some of the axes are inverted compared to that paper's biplots (i.e. here `Red` points to the right and `Blue` points to the left, whereas in the 2002 paper it's the opposite), but the interpretation should be the same.\n", "\n", "(One fun tidbit: if you're wondering why painting `20` here seems incorrectly placed compared to the A&G 2002 paper, it's because there's a small error in some of that paper's figures! See [here](https://github.com/biocore/qurro/pull/282#issuecomment-594256858) for details.)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "execution": { "iopub.execute_input": "2022-07-05T21:46:16.970486Z", "iopub.status.busy": "2022-07-05T21:46:16.970313Z", "iopub.status.idle": "2022-07-05T21:46:18.346441Z", "shell.execute_reply": "2022-07-05T21:46:18.345998Z" } }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "from plotting_helper import apca, draw_painting_biplot\n", "\n", "# Perform Aitchison PCA\n", "ordination = apca(table.astype(float))\n", "\n", "# Style and draw the biplot, using the first and second principal components\n", "# https://github.com/jupyter/notebook/issues/3523#issuecomment-534379015\n", "%matplotlib inline\n", "draw_painting_biplot(ordination, \"Axis 1\", \"Axis 2\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.1. Viewing the loadings from the biplot\n", "When we used Aitchison PCA above, we got a scikit-bio [OrdinationResults](http://scikit-bio.org/docs/latest/generated/skbio.stats.ordination.OrdinationResults.html) object. This contains the sample and feature loadings underlying the biplot that was generated, as well as some additional information. (If you're interested in more details, we encourage you to check out the `plotting_helper.py` code provided in this folder.)\n", "\n", "#### 2.1.1. Feature Loadings" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "execution": { "iopub.execute_input": "2022-07-05T21:46:18.348586Z", "iopub.status.busy": "2022-07-05T21:46:18.348359Z", "iopub.status.idle": "2022-07-05T21:46:18.354924Z", "shell.execute_reply": "2022-07-05T21:46:18.354555Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Axis 1Axis 2
FeatureID
Black0.064761-0.544208
White0.0200500.724314
Blue-0.5410210.119259
Red0.8228540.130236
Yellow-0.1533300.028251
\n", "
" ], "text/plain": [ " Axis 1 Axis 2\n", "FeatureID \n", "Black 0.064761 -0.544208\n", "White 0.020050 0.724314\n", "Blue -0.541021 0.119259\n", "Red 0.822854 0.130236\n", "Yellow -0.153330 0.028251" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ordination.features.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 2.1.2. Sample Loadings" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "execution": { "iopub.execute_input": "2022-07-05T21:46:18.356940Z", "iopub.status.busy": "2022-07-05T21:46:18.356770Z", "iopub.status.idle": "2022-07-05T21:46:18.362609Z", "shell.execute_reply": "2022-07-05T21:46:18.362116Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Axis 1Axis 2
SampleID
1-0.2018560.229034
2-0.0301620.070389
30.2875730.124102
4-0.064628-0.006208
5-0.159943-0.367294
\n", "
" ], "text/plain": [ " Axis 1 Axis 2\n", "SampleID \n", "1 -0.201856 0.229034\n", "2 -0.030162 0.070389\n", "3 0.287573 0.124102\n", "4 -0.064628 -0.006208\n", "5 -0.159943 -0.367294" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ordination.samples.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.2. Export the ordination information to a file\n", "This will enable us to use the feature loadings contained in this file as feature rankings in Qurro." ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "execution": { "iopub.execute_input": "2022-07-05T21:46:18.365121Z", "iopub.status.busy": "2022-07-05T21:46:18.364917Z", "iopub.status.idle": "2022-07-05T21:46:18.370805Z", "shell.execute_reply": "2022-07-05T21:46:18.370205Z" } }, "outputs": [ { "data": { "text/plain": [ "'output/apca-ordination.txt'" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ordination.write(\"output/apca-ordination.txt\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.3. Optional: merge the sample loadings into the sample metadata\n", "As we mentioned before, we don't really have a lot of information about these paintings. One thing we do have now, though, are loadings in the biplot for each sample. You can imagine visualizing these loadings in relation to a selected log-ratio—for example, as shown in the bottom four sub-figures of Fig. 5 in [Martino et al. 2019](https://msystems.asm.org/content/msys/4/1/e00016-19).\n", "\n", "Here we're going to merge these loadings with our previous metadata to generate an augmented metadata file, and we'll use that augmented metadata file in Qurro." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "execution": { "iopub.execute_input": "2022-07-05T21:46:18.373142Z", "iopub.status.busy": "2022-07-05T21:46:18.372949Z", "iopub.status.idle": "2022-07-05T21:46:18.390260Z", "shell.execute_reply": "2022-07-05T21:46:18.389692Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
proportion_blackproportion_whiteproportion_blueproportion_redproportion_yellowproportion_otherdata_sourceAxis 1Axis 2
SampleID
10.1250.2430.1530.0310.1810.266AitchisonGreenacre2002-0.2018560.229034
20.1430.2240.1110.0510.1590.313AitchisonGreenacre2002-0.0301620.070389
30.1470.2310.0580.1290.1330.303AitchisonGreenacre20020.2875730.124102
40.1640.2090.1200.0470.1780.282AitchisonGreenacre2002-0.064628-0.006208
50.1970.1510.1320.0330.1880.299AitchisonGreenacre2002-0.159943-0.367294
\n", "
" ], "text/plain": [ " proportion_black proportion_white proportion_blue proportion_red \\\n", "SampleID \n", "1 0.125 0.243 0.153 0.031 \n", "2 0.143 0.224 0.111 0.051 \n", "3 0.147 0.231 0.058 0.129 \n", "4 0.164 0.209 0.120 0.047 \n", "5 0.197 0.151 0.132 0.033 \n", "\n", " proportion_yellow proportion_other data_source Axis 1 \\\n", "SampleID \n", "1 0.181 0.266 AitchisonGreenacre2002 -0.201856 \n", "2 0.159 0.313 AitchisonGreenacre2002 -0.030162 \n", "3 0.133 0.303 AitchisonGreenacre2002 0.287573 \n", "4 0.178 0.282 AitchisonGreenacre2002 -0.064628 \n", "5 0.188 0.299 AitchisonGreenacre2002 -0.159943 \n", "\n", " Axis 2 \n", "SampleID \n", "1 0.229034 \n", "2 0.070389 \n", "3 0.124102 \n", "4 -0.006208 \n", "5 -0.367294 " ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "merged_metadata = metadata.merge(\n", " ordination.samples,\n", " how=\"left\",\n", " left_index=True,\n", " right_index=True,\n", " suffixes=(False, False)\n", ")\n", "merged_metadata.to_csv(\"output/merged-metadata.tsv\", sep=\"\\t\")\n", "merged_metadata.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Running Qurro\n", "\n", "Now that we have everything ready, we can finally use Qurro with this data.\n", "\n", "### 3.1. Listing the available command-line options" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "execution": { "iopub.execute_input": "2022-07-05T21:46:18.392380Z", "iopub.status.busy": "2022-07-05T21:46:18.392196Z", "iopub.status.idle": "2022-07-05T21:46:18.888167Z", "shell.execute_reply": "2022-07-05T21:46:18.887080Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Usage: qurro [OPTIONS]\r\n", "\r\n", " Generates a visualization of feature rankings and log-ratios.\r\n", "\r\n", " The resulting visualization contains two plots. The first plot shows how\r\n", " features are ranked, and the second plot shows the log-ratio of \"selected\"\r\n", " features' abundances within samples.\r\n", "\r\n", " The visualization is interactive, so which features are \"selected\" to\r\n", " construct log-ratios -- as well as various other properties of the\r\n", " visualization -- can be changed by the user.\r\n", "\r\n", "Options:\r\n", " -r, --ranks TEXT Either feature differentials (contained in a\r\n", " TSV file, where each row describes a feature\r\n", " and each column describes a differential\r\n", " field) or a scikit-bio OrdinationResults\r\n", " file for a biplot (containing feature\r\n", " loadings). When sorted numerically,\r\n", " differentials and feature loadings alike\r\n", " provide 'rankings.' [required]\r\n", "\r\n", " -t, --table TEXT A BIOM table describing the abundances of\r\n", " the ranked features in samples. Note that\r\n", " empty samples and features will be removed\r\n", " from the Qurro visualization. [required]\r\n", "\r\n", " -sm, --sample-metadata TEXT Sample metadata, formatted as a TSV file\r\n", " (where each row describes a sample and each\r\n", " column describes a 'metadata' field, and the\r\n", " first column contains sample IDs). In Qurro\r\n", " visualizations, you can use sample metadata\r\n", " fields to change the x-axis and colors in\r\n", " the sample plot. [required]\r\n", "\r\n", " -fm, --feature-metadata TEXT Feature metadata, formatted as a TSV file\r\n", " (where each row describes a feature and each\r\n", " column describes a 'metadata' field, and the\r\n", " first column contains feature IDs). In Qurro\r\n", " visualizations, you can use feature metadata\r\n", " fields to filter features in the rank plot\r\n", " when selecting log-ratios.\r\n", "\r\n", " -o, --output-dir TEXT Directory to write the HTML/JS/... files\r\n", " defining a Qurro visualization to. If this\r\n", " directory already exists, files/directories\r\n", " already within it will be overwritten if\r\n", " necessary. Note that you need to keep the\r\n", " files in this directory together -- moving\r\n", " the index.html file in this directory to\r\n", " another location, without also moving the\r\n", " JS/etc. files, will break the visualization.\r\n", " [required]\r\n", "\r\n", " -x, --extreme-feature-count INTEGER\r\n", " If specified, Qurro will only use this many\r\n", " \"extreme\" features from both ends of all of\r\n", " the rankings. This is useful when dealing\r\n", " with huge datasets (e.g. with BIOM tables\r\n", " exceeding 1 million entries), for which\r\n", " running Qurro normally might take a long\r\n", " amount of time or crash due to memory\r\n", " limits. Note that the automatic removal of\r\n", " empty samples and features from the table\r\n", " will be done *after* this filtering step.\r\n", "\r\n", " --debug If this flag is used, Qurro will output\r\n", " debug messages.\r\n", "\r\n", " --version Show the version and exit.\r\n", " --help Show this message and exit.\r\n" ] } ], "source": [ "!qurro --help" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.2. Generating a Qurro visualization\n", "Our inputs will be the following three files:\n", "\n", " - **Feature table:** The BIOM table we generated in section 1.1.3 above.\n", " \n", " \n", " - **Sample metadata:** The merged metadata file we generated in section 2.3 above.\n", " \n", " \n", " - **Feature rankings:** The feature loadings we exported in section 2.2 above." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "execution": { "iopub.execute_input": "2022-07-05T21:46:18.892221Z", "iopub.status.busy": "2022-07-05T21:46:18.891899Z", "iopub.status.idle": "2022-07-05T21:46:19.418979Z", "shell.execute_reply": "2022-07-05T21:46:19.417045Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Successfully generated a visualization in the folder output/qurro-viz/.\r\n" ] } ], "source": [ "!qurro \\\n", " --table output/color-table.biom \\\n", " --sample-metadata output/merged-metadata.tsv \\\n", " --ranks output/apca-ordination.txt \\\n", " --output-dir output/qurro-viz/" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.3. Interacting with the Qurro visualization\n", "\n", "The command you just ran will generate a folder containing the Qurro visualization. To view the visualization, you can just open up the `index.html` file contained within this folder in a web browser. You should see something like this:\n", "\n", "![](imgs/1.png)\n", "\n", "The top-left of the screen contains the **rank plot**: a plot showing the loadings for each feature for a selected axis or principal component. The top-right of the screen contains the **sample plot**: a plot that will show how a selected log-ratio of features looks for all of the samples.\n", "\n", "Things look pretty blank right now, since nothing is selected. Let's fix that!\n", "\n", "#### 3.3.1. Selecting a log-ratio\n", "\n", "One thing that's clear from looking at the biplot visualization we generated earlier is that `Red` and `Blue` seemed to differentiate samples along Axis 1. Looking at the rank plot for Axis 1 confirms this -- check out how the magnitudes of `Red` and `Blue` for the Axis 1 feature loadings are relatively larger than the other colors.\n", "\n", "So, let's try seeing how the `Red`:`Blue` log-ratio looks in Qurro. To select a log-ratio of individual features, you can just click on the rank plot -- the first click sets the new numerator and the second click sets the new denominator. In this case, we're going to click on the rightmost bar (`Red`), and then the leftmost bar (`Blue`).\n", "\n", "![](imgs/2.png)\n", "\n", "#### 3.3.2. Adjusting the sample plot\n", "\n", "The sample plot just looks like a bunch of noise! Mostly, this is because the way the sample plot x-axis is set up doesn't make sense: it's set to `proportion_black` (which we don't really have a reason to expect would be associated with the `Red`:`Blue` log-ratio), and its scale type is set to `Categorical` (despite the fact that `proportion_black` is a quantitative field). If we set the sample plot x-axis to `proportion_red`, and change up some of the other sample plot controls, we get a much more useful visualization:\n", "\n", "![](imgs/3.png)\n", "\n", "So we can see from here that the `Red`:`Blue` log-ratio is very correlated with the proportion of `Red` in a given painting. Hopefully this makes sense! All the sample plot is showing is that `ln(r / b)` is correlated with `r`, which shouldn't be too crazy.\n", "\n", "But we have some other things we can try out.\n", "\n", "#### 3.3.3. Relating feature log-ratios to sample loadings\n", "\n", "Remember the sample loadings we merged into the metadata a while back? We can use those here, and replicate the sorts of figures shown in Fig. 5 in [Martino et al. 2019](https://msystems.asm.org/content/msys/4/1/e00016-19).\n", "\n", "We know that `Red` and `Blue` differentiate samples along Axis 1, so let's look at how the Axis 1 sample loadings are correlated with the `Red`:`Blue` log-ratio. We already have that log-ratio selected, so all we need to do is change the sample plot x-axis field from `proportion_red` to `Axis 1`:\n", "\n", "![](imgs/4.png)\n", "\n", "That's cool. We can see that the `Red`:`Blue` log-ratio is highly correlated with the Axis 1 sample loadings of paintings, which confirms our observations from looking at the biplot visualization.\n", "\n", "#### 3.3.4. Trying additional log-ratios\n", "\n", "As an exercise for the reader: try switching the rank plot's `Feature Loading` to Axis 2, then try selecting the log-ratio of `White`:`Black`. How does this look when we view samples' Axis 1 sample loadings? How does this look when we view samples' Axis 2 sample loadings? (This is shown below.) What differences do you see, and why do you think these are the case?\n", "\n", "![](imgs/5.png)\n", "\n", "### 3.4. Finishing up; additional reading\n", "\n", "There are a few other functionalities in Qurro that we haven't covered here. We encourage you to check out the interface for yourself!\n", "\n", "There are a lot of ways to visualize compositional data, and a lot of ways to use Qurro in conjunction with a compositional biplot. **Our hope is that you interpret this document as less of a strict guide and more as a starting point for how to use Qurro**. In particular, [Aitchison and Greenacre (2002)](https://rss.onlinelibrary.wiley.com/doi/full/10.1111/1467-9876.00275), where we got this color composition data from, goes pretty in-depth in how to interpret compositional biplots -- we highly recommend checking that paper out to get a sense of what these results \"mean.\"\n", "\n", "Thanks for reading this tutorial! As always, please feel free to [open an issue](https://github.com/biocore/qurro/) in Qurro's repository (or ask a question on the [QIIME 2 forums](https://forum.qiime2.org/)) if you have any questions, comments, or suggestions." ] } ], "metadata": { "kernelspec": { "display_name": "Python [conda env:q2-2022.2-unfucked] *", "language": "python", "name": "conda-env-q2-2022.2-unfucked-py" }, "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.13" } }, "nbformat": 4, "nbformat_minor": 2 }