Skip to content

Instantly share code, notes, and snippets.

@manzt
Created May 9, 2022 16:31
Show Gist options
  • Save manzt/55c8429713abe01a51ecab0d6606d8c9 to your computer and use it in GitHub Desktop.
Save manzt/55c8429713abe01a51ecab0d6606d8c9 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "bd10791f",
"metadata": {},
"outputs": [],
"source": [
"!pip install git+https://github.com/manzt/hg.git@main # higlass-python v2"
]
},
{
"cell_type": "markdown",
"id": "a54e0845",
"metadata": {},
"source": [
"## Hello, `hg`!\n",
"\n",
"[`hg`](https://github.com/manzt/hg) is a new Python toolkit for HiGlass. It is planned as an official v2 for [`higlass-python`](https://github.com/higlass/higlass-python), with a focus on modularity and flexibilty. \n",
"\n",
"### Creating a Track\n",
"\n",
"At its core, `hg` is simply a library for authoring valid HiGlass view configurations in Python. A HiGlass viewconf is composed of _Tracks_ and _Views_. In `hg`, a _Track_ is created via the `hg.track` method:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "451e30ce",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"EnumTrack(tilesetUid='OHJakQICQD6gTD7skx4EWA', server='https://higlass.io/api/v1', type='horizontal-gene-annotations', uid='WGREL-aaQ4e2iP5d7bSG6w', width=None, height=60, options={'name': 'Gene Annotations (hg19)'}, data=None, chromInfoPath=None, fromViewUid=None, x=None, y=None)"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import hg\n",
"\n",
"my_track = hg.track(\n",
" \"horizontal-gene-annotations\", # track type\n",
" tilesetUid=\"OHJakQICQD6gTD7skx4EWA\",\n",
" server=\"https://higlass.io/api/v1\",\n",
" height=60,\n",
" options={\"name\": \"Gene Annotations (hg19)\"},\n",
")\n",
"\n",
"my_track"
]
},
{
"cell_type": "markdown",
"id": "0f214054",
"metadata": {},
"source": [
"## Creating a View\n",
"\n",
"In HiGlass, a _View_ combines one or more _Tracks_ together into a layout. The `hg.view` method accepts one or more tracks and creates an `hg.View` object:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "db0455f3",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"layout=Layout(x=0, y=0, w=12, h=6, moved=None, static=None) tracks=Tracks[TrackT](left=None, right=None, top=[EnumTrack(tilesetUid='OHJakQICQD6gTD7skx4EWA', server='https://higlass.io/api/v1', type='horizontal-gene-annotations', uid='WGREL-aaQ4e2iP5d7bSG6w', width=None, height=60, options={'name': 'Gene Annotations (hg19)'}, data=None, chromInfoPath=None, fromViewUid=None, x=None, y=None)], bottom=None, center=None, whole=None, gallery=None) uid='Ow7jtnZVSmyLrika3nLt9A' autocompleteSource=None chromInfoPath=None genomePositionSearchBox=None genomePositionSearchBoxVisible=None initialXDomain=None initialYDomain=None overlays=None selectionView=None zoomFixed=None zoomLimits=(1, None)\n"
]
}
],
"source": [
"my_view = hg.view(\n",
" (my_track, \"top\") # tuple of (Track, layout-position)\n",
")\n",
"print(my_view)"
]
},
{
"cell_type": "markdown",
"id": "6ad9d211",
"metadata": {},
"source": [
"In `hg`, we have implemented a custom HTML `repr` for an `hg.View` instance, which will display the view using the HiGlass client in the notebook. "
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "bd0b8e03",
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"<!DOCTYPE html>\n",
"<html>\n",
"<head>\n",
" <link rel=\"stylesheet\" href=\"https://unpkg.com/higlass@1.11/dist/hglib.css\">\n",
"</head>\n",
"<body>\n",
" <div id=\"jupyter-hg-ebb69a8775de40e7bc4c433be9b67073\"></div>\n",
" <script type=\"module\">\n",
"\n",
" async function loadScript(src) {\n",
" return new Promise(resolve => {\n",
" const script = document.createElement('script');\n",
" script.onload = resolve;\n",
" script.src = src;\n",
" script.async = false;\n",
" document.head.appendChild(script);\n",
" });\n",
" }\n",
"\n",
" async function loadHiglass() {\n",
" // need to manually load higlass; disable requirejs\n",
"\n",
" // https://github.com/DanielHreben/requirejs-toggle\n",
" window.__requirejsToggleBackup = {\n",
" define: window.define,\n",
" require: window.require,\n",
" requirejs: window.requirejs,\n",
" };\n",
"\n",
" for (const field of Object.keys(window.__requirejsToggleBackup)) {\n",
" window[field] = undefined;\n",
" }\n",
"\n",
" let sources = [];\n",
"\n",
" if (!window.hglib){\n",
" sources = sources.concat([\n",
" \"https://unpkg.com/react@17/umd/react.production.min.js\",\n",
" \"https://unpkg.com/react-dom@17/umd/react-dom.production.min.js\",\n",
" \"https://unpkg.com/pixi.js@6/dist/browser/pixi.min.js\",\n",
" \"https://unpkg.com/higlass@1.11/dist/hglib.js\",\n",
" ]);\n",
" }\n",
"\n",
" for (const src of sources) await loadScript(src);\n",
"\n",
" // restore requirejs after scripts have loaded\n",
" Object.assign(window, window.__requirejsToggleBackup);\n",
" delete window.__requirejsToggleBackup;\n",
"\n",
" return window.hglib;\n",
" };\n",
"\n",
" var el = document.getElementById('jupyter-hg-ebb69a8775de40e7bc4c433be9b67073');\n",
" var spec = JSON.parse(\"{\\\"editable\\\": true, \\\"viewEditable\\\": true, \\\"tracksEditable\\\": true, \\\"views\\\": [{\\\"layout\\\": {\\\"x\\\": 0, \\\"y\\\": 0, \\\"w\\\": 12, \\\"h\\\": 6}, \\\"tracks\\\": {\\\"top\\\": [{\\\"tilesetUid\\\": \\\"OHJakQICQD6gTD7skx4EWA\\\", \\\"server\\\": \\\"https://higlass.io/api/v1\\\", \\\"type\\\": \\\"horizontal-gene-annotations\\\", \\\"uid\\\": \\\"WGREL-aaQ4e2iP5d7bSG6w\\\", \\\"height\\\": 60, \\\"options\\\": {\\\"name\\\": \\\"Gene Annotations (hg19)\\\"}}]}, \\\"uid\\\": \\\"Ow7jtnZVSmyLrika3nLt9A\\\", \\\"zoomLimits\\\": [1, null]}]}\");\n",
"\n",
" loadHiglass().then(hglib => {\n",
" hglib.viewer(el, spec);\n",
" })\n",
" </script>\n",
"</body>\n",
"</html>"
],
"text/plain": [
"View(layout=Layout(x=0, y=0, w=12, h=6, moved=None, static=None), tracks=Tracks[TrackT](left=None, right=None, top=[EnumTrack(tilesetUid='OHJakQICQD6gTD7skx4EWA', server='https://higlass.io/api/v1', type='horizontal-gene-annotations', uid='WGREL-aaQ4e2iP5d7bSG6w', width=None, height=60, options={'name': 'Gene Annotations (hg19)'}, data=None, chromInfoPath=None, fromViewUid=None, x=None, y=None)], bottom=None, center=None, whole=None, gallery=None), uid='Ow7jtnZVSmyLrika3nLt9A', autocompleteSource=None, chromInfoPath=None, genomePositionSearchBox=None, genomePositionSearchBoxVisible=None, initialXDomain=None, initialYDomain=None, overlays=None, selectionView=None, zoomFixed=None, zoomLimits=(1, None))"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"my_view # renders with HiGlass"
]
},
{
"cell_type": "markdown",
"id": "62a98703",
"metadata": {},
"source": [
"## Thinking in Tilesets\n",
"\n",
"A core component of HiGlass is a `Tileset`, which represets a genomic data-source for a given track. Tilesets are specified in a `Track` via the `tilesetUid` and `server` properties, which can be quite repetitive if defining mulitple `Tracks` which share the same `Tileset`, e.g.,"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "38ade1be",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"<!DOCTYPE html>\n",
"<html>\n",
"<head>\n",
" <link rel=\"stylesheet\" href=\"https://unpkg.com/higlass@1.11/dist/hglib.css\">\n",
"</head>\n",
"<body>\n",
" <div id=\"jupyter-hg-184e57cced8f41caa82b980425e7fa72\"></div>\n",
" <script type=\"module\">\n",
"\n",
" async function loadScript(src) {\n",
" return new Promise(resolve => {\n",
" const script = document.createElement('script');\n",
" script.onload = resolve;\n",
" script.src = src;\n",
" script.async = false;\n",
" document.head.appendChild(script);\n",
" });\n",
" }\n",
"\n",
" async function loadHiglass() {\n",
" // need to manually load higlass; disable requirejs\n",
"\n",
" // https://github.com/DanielHreben/requirejs-toggle\n",
" window.__requirejsToggleBackup = {\n",
" define: window.define,\n",
" require: window.require,\n",
" requirejs: window.requirejs,\n",
" };\n",
"\n",
" for (const field of Object.keys(window.__requirejsToggleBackup)) {\n",
" window[field] = undefined;\n",
" }\n",
"\n",
" let sources = [];\n",
"\n",
" if (!window.hglib){\n",
" sources = sources.concat([\n",
" \"https://unpkg.com/react@17/umd/react.production.min.js\",\n",
" \"https://unpkg.com/react-dom@17/umd/react-dom.production.min.js\",\n",
" \"https://unpkg.com/pixi.js@6/dist/browser/pixi.min.js\",\n",
" \"https://unpkg.com/higlass@1.11/dist/hglib.js\",\n",
" ]);\n",
" }\n",
"\n",
" for (const src of sources) await loadScript(src);\n",
"\n",
" // restore requirejs after scripts have loaded\n",
" Object.assign(window, window.__requirejsToggleBackup);\n",
" delete window.__requirejsToggleBackup;\n",
"\n",
" return window.hglib;\n",
" };\n",
"\n",
" var el = document.getElementById('jupyter-hg-184e57cced8f41caa82b980425e7fa72');\n",
" var spec = JSON.parse(\"{\\\"editable\\\": true, \\\"viewEditable\\\": true, \\\"tracksEditable\\\": true, \\\"views\\\": [{\\\"layout\\\": {\\\"x\\\": 0, \\\"y\\\": 0, \\\"w\\\": 12, \\\"h\\\": 6}, \\\"tracks\\\": {\\\"left\\\": [{\\\"tilesetUid\\\": \\\"OHJakQICQD6gTD7skx4EWA\\\", \\\"server\\\": \\\"https://higlass.io/api/v1\\\", \\\"type\\\": \\\"vertical-gene-annotations\\\", \\\"uid\\\": \\\"IJumCyFmTz-42DmZcGVXAQ\\\", \\\"width\\\": 100, \\\"options\\\": {\\\"name\\\": \\\"Gene Annotations (hg19)\\\"}}], \\\"top\\\": [{\\\"tilesetUid\\\": \\\"OHJakQICQD6gTD7skx4EWA\\\", \\\"server\\\": \\\"https://higlass.io/api/v1\\\", \\\"type\\\": \\\"horizontal-gene-annotations\\\", \\\"uid\\\": \\\"EEmH1kU_S_yzTu8j3RsCvQ\\\", \\\"height\\\": 60, \\\"options\\\": {\\\"name\\\": \\\"Gene Annotations (hg19)\\\"}}]}, \\\"uid\\\": \\\"AH0rLQILTk6J_P90AGB4qw\\\", \\\"zoomLimits\\\": [1, null]}]}\");\n",
"\n",
" loadHiglass().then(hglib => {\n",
" hglib.viewer(el, spec);\n",
" })\n",
" </script>\n",
"</body>\n",
"</html>"
],
"text/plain": [
"View(layout=Layout(x=0, y=0, w=12, h=6, moved=None, static=None), tracks=Tracks[TrackT](left=[EnumTrack(tilesetUid='OHJakQICQD6gTD7skx4EWA', server='https://higlass.io/api/v1', type='vertical-gene-annotations', uid='IJumCyFmTz-42DmZcGVXAQ', width=100, height=None, options={'name': 'Gene Annotations (hg19)'}, data=None, chromInfoPath=None, fromViewUid=None, x=None, y=None)], right=None, top=[EnumTrack(tilesetUid='OHJakQICQD6gTD7skx4EWA', server='https://higlass.io/api/v1', type='horizontal-gene-annotations', uid='EEmH1kU_S_yzTu8j3RsCvQ', width=None, height=60, options={'name': 'Gene Annotations (hg19)'}, data=None, chromInfoPath=None, fromViewUid=None, x=None, y=None)], bottom=None, center=None, whole=None, gallery=None), uid='AH0rLQILTk6J_P90AGB4qw', autocompleteSource=None, chromInfoPath=None, genomePositionSearchBox=None, genomePositionSearchBoxVisible=None, initialXDomain=None, initialYDomain=None, overlays=None, selectionView=None, zoomFixed=None, zoomLimits=(1, None))"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"my_track = hg.track(\n",
" \"horizontal-gene-annotations\", # track type\n",
" tilesetUid=\"OHJakQICQD6gTD7skx4EWA\",\n",
" server=\"https://higlass.io/api/v1\",\n",
" height=60,\n",
" options={\"name\": \"Gene Annotations (hg19)\"},\n",
")\n",
"\n",
"my_track_left = hg.track(\n",
" \"vertical-gene-annotations\", # track type\n",
" tilesetUid=\"OHJakQICQD6gTD7skx4EWA\",\n",
" server=\"https://higlass.io/api/v1\",\n",
" width=100,\n",
" options={\"name\": \"Gene Annotations (hg19)\"},\n",
")\n",
"\n",
"hg.view(\n",
" (my_track, \"top\"),\n",
" (my_track_left, \"left\"),\n",
")"
]
},
{
"cell_type": "markdown",
"id": "baa5f6ab",
"metadata": {},
"source": [
"We introduce the concept of a `Tileset` in `hg` which makes creating tracks with the same data-souce much easier. The tilesets used in `my_track` and `my_track_left` specify the same _remote_ data-source on resgen. We can create a `Tileset` in `hg` that represents this shared remote data-source with `hg.remote`."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "a6ae5747",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"RemoteTileset(uid='OHJakQICQD6gTD7skx4EWA', server='https://higlass.io/api/v1', name='Gene Annotations (hg19)')"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"gene_anno_tileset = hg.remote(\n",
" uid=\"OHJakQICQD6gTD7skx4EWA\",\n",
" server=\"https://higlass.io/api/v1\",\n",
" name=\"Gene Annotations (hg19)\", # optional\n",
")\n",
"\n",
"rao_tileset = hg.remote(\n",
" uid=\"CQMd6V_cRw6iCI_-Unl3PQ\",\n",
" server=\"https://higlass.io/api/v1/\",\n",
" name=\"Rao et al. (2014) GM12878 MboI (allreps) 1kb\", # optional\n",
")\n",
"\n",
"gene_anno_tileset"
]
},
{
"cell_type": "markdown",
"id": "baf3b63d",
"metadata": {},
"source": [
"From the `Tileset` instance, we can create tracks much more easily:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "51a5645f",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"<!DOCTYPE html>\n",
"<html>\n",
"<head>\n",
" <link rel=\"stylesheet\" href=\"https://unpkg.com/higlass@1.11/dist/hglib.css\">\n",
"</head>\n",
"<body>\n",
" <div id=\"jupyter-hg-e597944b8a3041f4bb485730be299191\"></div>\n",
" <script type=\"module\">\n",
"\n",
" async function loadScript(src) {\n",
" return new Promise(resolve => {\n",
" const script = document.createElement('script');\n",
" script.onload = resolve;\n",
" script.src = src;\n",
" script.async = false;\n",
" document.head.appendChild(script);\n",
" });\n",
" }\n",
"\n",
" async function loadHiglass() {\n",
" // need to manually load higlass; disable requirejs\n",
"\n",
" // https://github.com/DanielHreben/requirejs-toggle\n",
" window.__requirejsToggleBackup = {\n",
" define: window.define,\n",
" require: window.require,\n",
" requirejs: window.requirejs,\n",
" };\n",
"\n",
" for (const field of Object.keys(window.__requirejsToggleBackup)) {\n",
" window[field] = undefined;\n",
" }\n",
"\n",
" let sources = [];\n",
"\n",
" if (!window.hglib){\n",
" sources = sources.concat([\n",
" \"https://unpkg.com/react@17/umd/react.production.min.js\",\n",
" \"https://unpkg.com/react-dom@17/umd/react-dom.production.min.js\",\n",
" \"https://unpkg.com/pixi.js@6/dist/browser/pixi.min.js\",\n",
" \"https://unpkg.com/higlass@1.11/dist/hglib.js\",\n",
" ]);\n",
" }\n",
"\n",
" for (const src of sources) await loadScript(src);\n",
"\n",
" // restore requirejs after scripts have loaded\n",
" Object.assign(window, window.__requirejsToggleBackup);\n",
" delete window.__requirejsToggleBackup;\n",
"\n",
" return window.hglib;\n",
" };\n",
"\n",
" var el = document.getElementById('jupyter-hg-e597944b8a3041f4bb485730be299191');\n",
" var spec = JSON.parse(\"{\\\"editable\\\": true, \\\"viewEditable\\\": true, \\\"tracksEditable\\\": true, \\\"views\\\": [{\\\"layout\\\": {\\\"x\\\": 0, \\\"y\\\": 0, \\\"w\\\": 12, \\\"h\\\": 6}, \\\"tracks\\\": {\\\"left\\\": [{\\\"tilesetUid\\\": \\\"OHJakQICQD6gTD7skx4EWA\\\", \\\"server\\\": \\\"https://higlass.io/api/v1\\\", \\\"type\\\": \\\"vertical-gene-annotations\\\", \\\"uid\\\": \\\"Cy2OoH6kR-iHzWvhJh0h6w\\\", \\\"height\\\": 60, \\\"options\\\": {\\\"name\\\": \\\"Gene Annotations (hg19)\\\"}}], \\\"top\\\": [{\\\"tilesetUid\\\": \\\"OHJakQICQD6gTD7skx4EWA\\\", \\\"server\\\": \\\"https://higlass.io/api/v1\\\", \\\"type\\\": \\\"horizontal-gene-annotations\\\", \\\"uid\\\": \\\"EZr3G6rBQMmLCxiRjbSaEg\\\", \\\"height\\\": 60, \\\"options\\\": {\\\"name\\\": \\\"Gene Annotations (hg19)\\\"}}], \\\"center\\\": [{\\\"tilesetUid\\\": \\\"CQMd6V_cRw6iCI_-Unl3PQ\\\", \\\"server\\\": \\\"https://higlass.io/api/v1/\\\", \\\"type\\\": \\\"heatmap\\\", \\\"uid\\\": \\\"YqSSWrZIRcKx8KXcyt-kaw\\\", \\\"options\\\": {\\\"name\\\": \\\"Rao et al. (2014) GM12878 MboI (allreps) 1kb\\\"}}]}, \\\"uid\\\": \\\"LsFB2hNARMWO86h6NgwcSQ\\\", \\\"zoomLimits\\\": [1, null]}]}\");\n",
"\n",
" loadHiglass().then(hglib => {\n",
" hglib.viewer(el, spec);\n",
" })\n",
" </script>\n",
"</body>\n",
"</html>"
],
"text/plain": [
"View(layout=Layout(x=0, y=0, w=12, h=6, moved=None, static=None), tracks=Tracks[TrackT](left=[EnumTrack(tilesetUid='OHJakQICQD6gTD7skx4EWA', server='https://higlass.io/api/v1', type='vertical-gene-annotations', uid='Cy2OoH6kR-iHzWvhJh0h6w', width=None, height=60, options={'name': 'Gene Annotations (hg19)'}, data=None, chromInfoPath=None, fromViewUid=None, x=None, y=None)], right=None, top=[EnumTrack(tilesetUid='OHJakQICQD6gTD7skx4EWA', server='https://higlass.io/api/v1', type='horizontal-gene-annotations', uid='EZr3G6rBQMmLCxiRjbSaEg', width=None, height=60, options={'name': 'Gene Annotations (hg19)'}, data=None, chromInfoPath=None, fromViewUid=None, x=None, y=None)], bottom=None, center=[HeatmapTrack(tilesetUid='CQMd6V_cRw6iCI_-Unl3PQ', server='https://higlass.io/api/v1/', type='heatmap', uid='YqSSWrZIRcKx8KXcyt-kaw', width=None, height=None, options={'name': 'Rao et al. (2014) GM12878 MboI (allreps) 1kb'}, data=None, position=None, transforms=None)], whole=None, gallery=None), uid='LsFB2hNARMWO86h6NgwcSQ', autocompleteSource=None, chromInfoPath=None, genomePositionSearchBox=None, genomePositionSearchBoxVisible=None, initialXDomain=None, initialYDomain=None, overlays=None, selectionView=None, zoomFixed=None, zoomLimits=(1, None))"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hg.view(\n",
" (gene_anno_tileset.track(\"horizontal-gene-annotations\", height=60), \"top\"),\n",
" (gene_anno_tileset.track(\"vertical-gene-annotations\", height=60), \"left\"),\n",
" (rao_tileset.track(\"heatmap\"), \"center\"),\n",
")"
]
},
{
"cell_type": "markdown",
"id": "c38856e3",
"metadata": {},
"source": [
"## Local Tilesets\n",
"\n",
"An important feature of `hg` is its ability to host local data-sources (via a background server) to power a HiGlass visualization. Currently only `bigwig`, `cooler` and `multivec` formats are implemented, but _any_ implementation from `clodius.tiles` can easily be supported (https://github.com/higlass/clodius/tree/develop/clodius/tiles). "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8b2d90e9",
"metadata": {},
"outputs": [],
"source": [
"!pip install clodius # using the local server requires clodius to be installed"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "02a3bc9a",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'./test.mcool'"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import cooltools # just needed to load a dummy dataset\n",
"\n",
"cool_file = cooltools.download_data(\"HFF_MicroC\", cache=True, data_dir='./')\n",
"cool_file"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "a3d8dbc2",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"<!DOCTYPE html>\n",
"<html>\n",
"<head>\n",
" <link rel=\"stylesheet\" href=\"https://unpkg.com/higlass@1.11/dist/hglib.css\">\n",
"</head>\n",
"<body>\n",
" <div id=\"jupyter-hg-1a37ba83df204309b6269bf1d02dd702\"></div>\n",
" <script type=\"module\">\n",
"\n",
" async function loadScript(src) {\n",
" return new Promise(resolve => {\n",
" const script = document.createElement('script');\n",
" script.onload = resolve;\n",
" script.src = src;\n",
" script.async = false;\n",
" document.head.appendChild(script);\n",
" });\n",
" }\n",
"\n",
" async function loadHiglass() {\n",
" // need to manually load higlass; disable requirejs\n",
"\n",
" // https://github.com/DanielHreben/requirejs-toggle\n",
" window.__requirejsToggleBackup = {\n",
" define: window.define,\n",
" require: window.require,\n",
" requirejs: window.requirejs,\n",
" };\n",
"\n",
" for (const field of Object.keys(window.__requirejsToggleBackup)) {\n",
" window[field] = undefined;\n",
" }\n",
"\n",
" let sources = [];\n",
"\n",
" if (!window.hglib){\n",
" sources = sources.concat([\n",
" \"https://unpkg.com/react@17/umd/react.production.min.js\",\n",
" \"https://unpkg.com/react-dom@17/umd/react-dom.production.min.js\",\n",
" \"https://unpkg.com/pixi.js@6/dist/browser/pixi.min.js\",\n",
" \"https://unpkg.com/higlass@1.11/dist/hglib.js\",\n",
" ]);\n",
" }\n",
"\n",
" for (const src of sources) await loadScript(src);\n",
"\n",
" // restore requirejs after scripts have loaded\n",
" Object.assign(window, window.__requirejsToggleBackup);\n",
" delete window.__requirejsToggleBackup;\n",
"\n",
" return window.hglib;\n",
" };\n",
"\n",
" var el = document.getElementById('jupyter-hg-1a37ba83df204309b6269bf1d02dd702');\n",
" var spec = JSON.parse(\"{\\\"editable\\\": true, \\\"viewEditable\\\": true, \\\"tracksEditable\\\": true, \\\"views\\\": [{\\\"layout\\\": {\\\"x\\\": 0, \\\"y\\\": 0, \\\"w\\\": 12, \\\"h\\\": 6}, \\\"tracks\\\": {\\\"left\\\": [{\\\"tilesetUid\\\": \\\"ac9caa32806b577b186b04d984cd9a30\\\", \\\"server\\\": \\\"http://localhost:15289/api/v1/\\\", \\\"type\\\": \\\"vertical-chromosome-labels\\\", \\\"uid\\\": \\\"L-3KTq9_TOiOxkdNJawb6g\\\"}], \\\"top\\\": [{\\\"tilesetUid\\\": \\\"ac9caa32806b577b186b04d984cd9a30\\\", \\\"server\\\": \\\"http://localhost:15289/api/v1/\\\", \\\"type\\\": \\\"horizontal-chromosome-labels\\\", \\\"uid\\\": \\\"FuovGKKZQ-2hI3-N5DUDnQ\\\"}], \\\"center\\\": [{\\\"tilesetUid\\\": \\\"ac9caa32806b577b186b04d984cd9a30\\\", \\\"server\\\": \\\"http://localhost:15289/api/v1/\\\", \\\"type\\\": \\\"heatmap\\\", \\\"uid\\\": \\\"V7ypRXFCTB6oIvtAFXW4Bg\\\"}]}, \\\"uid\\\": \\\"YPkgU03OR9ai_Ve_0Mnixg\\\", \\\"zoomLimits\\\": [1, null]}]}\");\n",
"\n",
" loadHiglass().then(hglib => {\n",
" hglib.viewer(el, spec);\n",
" })\n",
" </script>\n",
"</body>\n",
"</html>"
],
"text/plain": [
"View(layout=Layout(x=0, y=0, w=12, h=6, moved=None, static=None), tracks=Tracks[TrackT](left=[EnumTrack(tilesetUid='ac9caa32806b577b186b04d984cd9a30', server='http://localhost:15289/api/v1/', type='vertical-chromosome-labels', uid='L-3KTq9_TOiOxkdNJawb6g', width=None, height=None, options=None, data=None, chromInfoPath=None, fromViewUid=None, x=None, y=None)], right=None, top=[EnumTrack(tilesetUid='ac9caa32806b577b186b04d984cd9a30', server='http://localhost:15289/api/v1/', type='horizontal-chromosome-labels', uid='FuovGKKZQ-2hI3-N5DUDnQ', width=None, height=None, options=None, data=None, chromInfoPath=None, fromViewUid=None, x=None, y=None)], bottom=None, center=[HeatmapTrack(tilesetUid='ac9caa32806b577b186b04d984cd9a30', server='http://localhost:15289/api/v1/', type='heatmap', uid='V7ypRXFCTB6oIvtAFXW4Bg', width=None, height=None, options=None, data=None, position=None, transforms=None)], whole=None, gallery=None), uid='YPkgU03OR9ai_Ve_0Mnixg', autocompleteSource=None, chromInfoPath=None, genomePositionSearchBox=None, genomePositionSearchBoxVisible=None, initialXDomain=None, initialYDomain=None, overlays=None, selectionView=None, zoomFixed=None, zoomLimits=(1, None))"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tileset = hg.cooler('./test.mcool') # returns a `LocalTileset` which can be used identially to a `RemoteTileset`\n",
"\n",
"view = hg.view(\n",
" (tileset.track(\"horizontal-chromosome-labels\"), \"top\"),\n",
" (tileset.track(\"vertical-chromosome-labels\"), \"left\"),\n",
" (tileset.track(\"heatmap\"), \"center\"),\n",
")\n",
"\n",
"view"
]
},
{
"cell_type": "markdown",
"id": "8f5a5273",
"metadata": {},
"source": [
"## Integrated Widget\n",
"\n",
"So far the visualizations rendered in the cells above cannot be interacted with in Python. The `hg.View.widget()` method returns a live `HiGlassWidget` which can be integrated with other Jupyter Widgets. Below, we will make a simple dropdown which navigates the HiGlass widget to each chromosome in the sample dataset.\n",
"\n",
"> Note, HiGlass currently relies on _absolute_ positions in the viewer so we must convert chromosome intervals to aboslute positions."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "517158d2",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"([['chr2', 242193529], ['chr17', 83257441]], [0, 242193529, 325450970])"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import itertools\n",
"from operator import itemgetter\n",
"\n",
"# extract chromsizes from tileset and compute absolute offsets\n",
"chromsizes = tileset.tileset.info()[\"chromsizes\"]\n",
"offsets = list(itertools.accumulate(map(itemgetter(1), chromsizes), initial=0))\n",
"chromsizes, offsets"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "3482a1f9",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "0d795f31e2e547ebb6018ee1c362ab2c",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"VBox(children=(Dropdown(options=(['chr2', 242193529], ['chr17', 83257441]), value=242193529), HiGlassWidget())…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import ipywidgets\n",
"\n",
"# a jupyter widget for the higlass viewer\n",
"higlass_widget = view.widget()\n",
"\n",
"# a dropdown widget\n",
"dropdown = ipywidgets.Dropdown(options=chromsizes)\n",
"\n",
"def handle_change(e):\n",
" \"\"\"Connects dropdown menu to HiGlassWidget instance\"\"\"\n",
" \n",
" # make sure it's a \"change\" event and the value of \"new\" is the index of the option\n",
" if e[\"type\"] == \"change\" and e[\"name\"] == \"index\":\n",
" index = e[\"new\"]\n",
" \n",
" start = offsets[index]\n",
" end = offsets[index + 1]\n",
" \n",
" # navigate higlass viewer\n",
" higlass_widget.zoom_to(\n",
" view.uid,\n",
" start, end,\n",
" start, end)\n",
" \n",
"\n",
"# connect our function above to the dropdown menu\n",
"dropdown.observe(handle_change)\n",
"\n",
"# NB - there seems to be a bug the first time you engage with the dropdown. Try again and things should work...\n",
"ipywidgets.VBox([dropdown, higlass_widget])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a28bcf6b",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"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.9.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment