{
    "componentChunkName": "component---src-templates-article-page-js",
    "path": "/journals/biology/micropub-biology-002120",
    "result": {"data":{"article":{"manuscript":{"id":"f52eaf7d-d071-4cc4-927e-14ecd4e9a4eb","submissionTypes":["methodology"],"citations":[],"doi":"10.17912/micropub.biology.002120","dbReferenceId":"","pmcId":"","pmId":"","proteopedia":"","reviewPanel":"","species":["drosophila"],"integrations":[],"corrections":null,"history":{"received":"2026-01-23T21:05:48.347Z","revisionReceived":"2026-03-11T17:57:52.679Z","accepted":"2026-03-27T20:52:32.710Z","published":"2026-04-02T16:55:15.755Z","indexed":"2026-04-16T16:55:15.755Z"},"versions":[{"id":"561ece5b-cf99-4ca2-8c7c-2f74a405ec63","decision":"revise","abstract":"<p>Modern microscopy generates multidimensional images. Graphical user interfaces allow visualization of multidimensional images, but image exploration is significantly harder in text-based environments. These include Jupyter notebooks, popular for the distribution of data analysis pipelines; and the terminal, often the only user interface available when accessing images in remote servers. We developed JuNkIE-CLImax, a pair of multidimensional image explorers designed to work in Jupyter notebooks and the terminal, respectively. JuNkIE-CLImax are written in Python, using Rust extensions to optimize performance; they are platform agnostic; and they provide application programming interfaces that enable integration into complex image visualization and analysis pipelines.</p>","acknowledgements":"<p>We are grateful to Negar Balaghi, Alexandra Korolov and Willow Peterson for comments on the manuscript. </p>","authors":[{"affiliations":["University of Toronto, Toronto, ON, CA","University of Toronto, Toronto, ON, CA","University of Toronto, Toronto, ON, CA","Hospital for Sick Children, Toronto, ON, CA"],"departments":["Institute of Biomedical Engineering","Ted Rogers Centre for Heart Research, Translational Biology and Engineering Program","Department of Cell and Systems Biology","Developmental and Stem Cell Biology Program"],"credit":["conceptualization","fundingAcquisition","methodology","project","resources","software","supervision","validation","visualization","writing_originalDraft","writing_reviewEditing","investigation"],"email":"rodrigo.fernandez.gonzalez@utoronto.ca","firstName":"Rodrigo","lastName":"Fernandez-Gonzalez","submittingAuthor":true,"correspondingAuthor":true,"equalContribution":false,"WBId":null,"orcid":"0000-0003-0770-744X"},{"affiliations":["University of Toronto, Toronto, ON, CA","University of Toronto, Toronto, ON, CA"],"departments":["Institute of Biomedical Engineering","Ted Rogers Centre for Heart Research, Translational Biology and Engineering Program"],"credit":["software","writing_reviewEditing"],"email":"raymond.hawkins@mail.utoronto.ca","firstName":"Raymond","lastName":"Hawkins","submittingAuthor":false,"correspondingAuthor":false,"equalContribution":false,"WBId":null,"orcid":null}],"awards":[],"conflictsOfInterest":"<p>The authors declare that there are no conflicts of interest present.</p>","dataTable":null,"extendedData":[],"funding":"<p>This work was supported by the Natural Sciences and Engineering Research Council of Canada (418438-13), the Canadian Institutes of Health Research (186188), the Canada Foundation for Innovation (30279), the Translational Biology and Engineering Program of the Ted Rogers Centre for Heart Research., and the University of Toronto EMHSeed Program. RFG is the Canada Research Chair in Quantitative Cell Biology and Morphogenesis.</p>","image":{"url":"https://portal.micropublication.org/uploads/e51ebf218e7555933af8a13dcfbec3be.png"},"imageCaption":"<p><b>(A)</b> JuNkIE (top) and CLImax (bottom) user interfaces displaying multidimensional images in a notebook and the terminal, respectively. JuNkIE-CLImax provide widgets to browse different image dimensions; expose multiple colormaps, including scientific colormaps; and conduct simple image operations, including rotation, flipping, zooming, reslicing and contrast adjustment. <b>(B)</b> Character-based image rendering. Sample image (left) and corresponding rich Style strings to render the image in the terminal (right), using a half-block character to display each pair of vertically-adjacent pixels. For instance, the Style parsed from \"<i>rgb(255,0,0) on rgb(0,255,255)</i>\", when associated with the half-block character, renders a red half-block on a cyan background, representing a cyan pixel in the top row and a red pixel in the bottom row, respectively<i>. </i>End-of-line characters (\"\\n\") indicate the ends of pairs of rows.</p>","imageTitle":"<p><b>JuNkIE-CLImax: multidimensional image explorers for notebooks and the terminal</b></p>","methods":"<p></p>","reagents":"<p></p>","patternDescription":"<p>Quantitative image analysis of microscopy datasets is a central tool in modern cell and developmental biology (Meijering and Cappellen, 2007; Senft et al., 2023). The advent of machine learning methods has established Python as the <i>de facto</i> standard for the analysis of biomedical images (Jacquemet, 2021; Morgado et al., 2024). Jupyter notebooks (Granger and Pérez, 2021) provide a beginner-friendly environment that enables prototyping and distribution&nbsp; of complex image processing pipelines (von Chamier et al., 2021). Platforms such as Google Colab or DigitalOcean provide free access to high-end computing capacity to execute notebooks, thus \"democratizing\" the use of resources that would otherwise be too costly. Notebooks facilitate data exploration and increase the reproducibility of data processing pipelines (Kluyver et al., 2016; Pimentel et al., 2019; Samuel and Mietchen, 2024). The leading position of notebooks for data analysis is cemented by the recent availability of large language models within notebooks (Qiu, 2023), which further facilitates development, debugging and execution of image processing and quantification routines. Thus, notebooks are a central element in the analysis of biomedical image data.</p><p>Both biological and medical imaging generate multidimensional data. Confocal and light sheet microscopies, for instance, allow collection of three-dimensional stacks (X, Y, Z) of different fluorescent reporters (wavelength), over the duration of a biological process (time). Multimodality imaging, such as correlative confocal and electron microscopies (Casares-Arias et al., 2021), confocal and super-resolution (Xiang et al., 2018), or the combination of anatomical and functional data in medical imaging (Pichler et al., 2008), introduces a sixth imaging dimension. Processing and analysis of multidimensional image datasets often requires image exploration at many stages in which rapid visualization and browsing are key steps. Two-dimensional images can be easily displayed in notebooks, <i>e.g.</i> with <i>matplotlib</i> (Hunter, 2007). However, few tools exist to display, browse and interact with multidimensional images in a notebook (Haase, 2021), and some of the available options provide complex user interfaces and functionality that prevent light-weight, inline multidimensional image browsing (Sofroniew et al., 2025).</p><p>Microscopy images are generally archived in remote backup servers. The advent of cloud-based storage services has only increased this trend. &nbsp;Remote and cloud-based servers often do not provide a graphical user interface, but simply a terminal-based, command line interface. Terminals can display text-based information about the images (file name, size, date, etc.), but do not allow image visualization. The lack of tools for image display on the terminal makes it hard to select images either for further processing or to generate figures for publication.</p><p>Here we introduce JuNkIE-CLImax, a pair of open source tools (https://bitbucket.org/rfg_lab/junkie and https://bitbucket.org/rfg_lab/climax) for the display and interactive visualization of multidimensional microscopy images in environments traditionally considered to be document or text-based. JuNkIE is a JUpyter NotebooK Image Explorer that enables the opening, display and simple manipulation of multidimensional images in Jupyter notebooks. CLImax, a Command Line IMAge eXplorer, allows users to open, visualize and browse multidimensional images on the terminal, using character-based strategies for image rendering. </p><p></p><p>JuNkIE-CLImax: multidimensional image explorers</p><p>JuNkIE-CLImax can load multidimensional images in the multi-page TIFF format often found in microscopy (Besson et al., 2019), as well as images stored in the increasingly popular <i>zarr</i> array format (Miles, 2015). JuNkIE-CLImax can also import file sequences that represent different dimensions (<i>e.g.</i> time or wavelength) of a multidimensional image. Internally, images are stored using <i>numpy</i>, a package for numerical computation, and its <i>ndarray</i> data structure to represent multidimensional arrays (Harris et al., 2020). JuNkIE-CLImax display a two-dimensional view of a multidimensional image (Fig. 1A). Both packages provide sliders to select a specific Z-plane, time point and channel from the multidimensional image stored in memory, using both mouse and keyboard-based interactions. JuNkIE-CLImax continuously update the displayed image in real time in response to user input. To enable use in settings with reduced compute power (<i>e.g.</i> remote storage servers), it is possible to disable the continuous update of the display, such that updates only occur when the user interaction is completed (<i>e.g.</i> when the mouse button is released, but not while the mouse is dragged). XY, XZ or YZ sectioning planes can be selected. Additionally, JuNkIE-CLImax provide functionality for simple image manipulation. This includes rotation and flipping (both horizontal and vertical), colormap selection and inversion (including all the colormaps available in <i>matplotlib</i> (Crameri et al., 2020; Crameri, 2023)), and both manual and automated contrast adjustment.</p><p></p><p><b><i>JuNkIE</i></b></p><p>JuNkIE displays images using the <i>Figure</i> class in <i>matplotlib</i>. A <i>matplotlib</i> <i>Figure</i> can hold different plot elements, including images. The <i>matplotlib</i> <i>Figure</i> provides a toolbar with options to pan, zoom in and out, reset the view, or save a snapshot (Fig. 1A, top).</p><p>JuNkIE provides a simple application programming interface (API). Using the JuNkIE API it is possible to open images from disk, by providing a file or folder path, or to view volumetric information already loaded as an <i>ndarray</i>. Substrings can be used to distinguish which files in an image sequence store specific dimensions (<i>e.g.</i> different image channels). Lastly, the colormap used to initially display an image, as well as the size of the figure can be used as input parameters when invoking JuNkIE.&nbsp;&nbsp;&nbsp;&nbsp;</p><p>JuNkIE is distributed with a test suite using <i>pytest</i> (Krekel et al., 2004) and the <i>nbval</i> plugin for notebook-based testing (Cortes-Ortuno et al., 2016), with code coverage over 90%.</p><p></p><p><b><i>CLImax</i></b></p><p>To display images on the terminal, we created a character-based image renderer. The image renderer uses <i>rich</i>, a Python package for text formatting that allows the use of coloured characters in the terminal (McGugan, 2019; Burns, 2022). Our image renderer takes a two-dimensional <i>ndarray</i> as its input, and produces a sequence of <i>rich</i> Segments, each consisting of a character and some formatting (a <i>Style</i>), punctuated by end-of-line characters at the end of each image row (Fig. 1B). <i>rich Styles</i> determine the colours used to display a character and its background. Colours are defined by the corresponding red, green and blue (rgb) components, specified as a string. Initially, we rendered each pixel using a space character (' '), assigning the pixel value as the background colour and no foreground colour. Because characters on the terminal are rectangular (elongated along the vertical axis), we rendered each image column twice to obtain square pixels. As a consequence, image rendering was relatively slow, requiring 380±23 ms (mean±standard deviation) to render a 512x672 pixel image on an Apple M3 Max equipped with 48 GB of RAM.</p><p>To optimize image rendering, we first reduced the number of terminal characters necessary to display a pixel. We took advantage of the half-block character ('▄') to visualize pairs of vertically-adjacent pixels (same column, consecutive rows) with a single terminal character (Fig. 1B). For each pair of pixels, we rendered the bottom pixel by assigning its value as the foreground colour of a half-block character, and the top pixel by assigning its value as the background colour of the same half-block character (Fig. 1B). This approach allowed us to display each pixel with half a character, in contrast to the previous method, which required two characters per pixel. We further accelerated rendering by creating a <i>Style</i> cache that used a Python dictionary to store the <i>rich</i> <i>Styles</i> corresponding to parsed colour-strings. After these optimizations, rendering speed increased by 57% (163±13 ms/image) and memory consumption decreased by a factor of four.</p><p>To further speed up image display, we implemented the hot-loop of the renderer in Rust (Matsakis and Klock II, 2014). The Rust code implements a helper function with two inputs, a two-dimensional image, and a colour lookup table that contains the string representation of each of the colours available in the current colormap. The helper function then scans the image columns, two rows at a time, generating the <i>Style</i> string for the character that will display a pair of vertically-adjacent pixels. We parallelized the scan over the image columns using the Rust crate <i>rayon</i> (Matsakis and Stone, 2014) to create a parallel iterator. Overall, Rust-based image rendering was 11% faster (146±13 ms/image) than our fastest Python implementation.</p><p>We designed the CLImax user interface with <i>textual</i> (McGugan, 2021) (Fig. 1A, bottom). <i>textual</i> is a Python package for the development of user interfaces and applications for the terminal. <i>textual</i> provides different widgets (<i>e.g.</i> buttons, dropdown boxes, text labels, etc.). We created a new <i>ImagePanel</i> widget that displays an image using the character-based renderer described above. <i>textual</i> apps provide a command palette that includes options to change the theme used to display the application, save a screenshot, or show a help panel. In addition, CLImax provides options to open a new image, zoom in or out, display the image with bilinear interpolation (particularly useful when zooming in/out), or save the current display.</p><p>CLImax can be invoked from the command line with different options. Similar to the JuNkIE API, the CLImax command line parameters enable image selection and substring and colour map specification, as well as initial zoom level, particularly important given that image rendering in the terminal is computationally intensive, with a cost that increases with the number of pixels to be rendered.</p><p>CLImax is also tested with <i>pytest</i>, using the <i>asyncio</i> plugin (Seifert, 2015) to test asynchronous user interaction. CLImax tests provide code coverage greater than 90%.</p>","references":[{"reference":"<p>Besson,S. <i>et al.</i> (2019) Bringing Open Data to Whole Slide Imaging. In, Reyes-Aldasoro,C.C. <i>et al.</i> (eds), <i>Digital Pathology</i>. Springer International Publishing, Cham, pp. 3–10.</p>","pubmedId":"","doi":""},{"reference":"<p>Burns,D. (2022) rich-pixels, https://github.com/darrenburns/rich-pixels.</p>","pubmedId":"","doi":""},{"reference":"<p>Casares-Arias,J. <i>et al.</i> (2021) Correlative confocal and scanning electron microscopy of cultured cells without using dedicated equipment. <i>STAR Protoc.</i>, <b>2</b>, 100727.</p>","pubmedId":"","doi":""},{"reference":"<p>von Chamier,L. <i>et al.</i> (2021) Democratising deep learning for microscopy with ZeroCostDL4Mic. <i>Nat Commun</i>, <b>12</b>, 2276.</p>","pubmedId":"","doi":""},{"reference":"<p>Cortes-Ortuno,D. <i>et al.</i> (2016) nbval, https://github.com/computationalmodelling/nbval.</p>","pubmedId":"","doi":""},{"reference":"<p>Crameri,F. (2023) Scientific colour maps, https://zenodo.org/records/8409685.</p>","pubmedId":"","doi":""},{"reference":"<p>Crameri,F. <i>et al.</i> (2020) The misuse of colour in science communication. <i>Nat. Commun.</i>, <b>11</b>, 5444.</p>","pubmedId":"","doi":""},{"reference":"<p>Granger,B.E. and Pérez,F. (2021) Jupyter: Thinking and Storytelling With Code and Data. <i>Comput. Sci. Eng.</i>, <b>23</b>, 7–14.</p>","pubmedId":"","doi":""},{"reference":"<p>Haase,R. (2021) stackview, https://github.com/haesleinhuepf/stackview.</p>","pubmedId":"","doi":""},{"reference":"<p>Harris,C.R. <i>et al.</i> (2020) Array programming with NumPy. <i>Nature</i>, <b>585</b>, 357–362.</p>","pubmedId":"","doi":""},{"reference":"<p>Hunter,J.D. (2007) Matplotlib: A 2D Graphics Environment. <i>Comput. Sci. Eng.</i>, <b>9</b>, 90–95.</p>","pubmedId":"","doi":""},{"reference":"<p>Jacquemet,G. (2021) Deep learning to analyse microscopy images. <i>The Biochemist</i>, <b>43</b>, 60–64.</p>","pubmedId":"","doi":""},{"reference":"<p>Kluyver,T. <i>et al.</i> (2016) Jupyter Notebooks – a publishing format for reproducible computational workflows.</p>","pubmedId":"","doi":""},{"reference":"<p>Krekel,H. <i>et al.</i> (2004) pytest, https://github.com/pytest-dev/pytest.</p>","pubmedId":"","doi":""},{"reference":"<p>Matsakis,N.D. and Klock II,F.S. (2014) The rust language. In, <i>ACM SIGAda Ada Letters</i>. ACM, pp. 103–104.</p>","pubmedId":"","doi":""},{"reference":"<p>Matsakis,N.D. and Stone,J. (2014) Rayon: A data parallelism library for Rust, https://github.com/rayon-rs/rayon/.</p>","pubmedId":"","doi":""},{"reference":"<p>McGugan,W. (2019) rich, https://github.com/Textualize/rich.</p>","pubmedId":"","doi":""},{"reference":"<p>McGugan,W. (2021) Textual, https://textual.textualize.io/.</p>","pubmedId":"","doi":""},{"reference":"<p>Meijering,E. and Cappellen,G. van (2007) Quantitative Biological Image Analysis. In, Shorte,S.L. and Frischknecht,F. (eds), <i>Imaging Cellular and Molecular Biological Functions</i>. Springer, Berlin, Heidelberg, pp. 45–70.</p>","pubmedId":"","doi":""},{"reference":"<p>Miles,A. (2015) zarr, https://github.com/zarr-developers/zarr-python.</p>","pubmedId":"","doi":""},{"reference":"<p>Morgado,L. <i>et al.</i> (2024) The rise of data-driven microscopy powered by machine learning. <i>J. Microsc.</i>, <b>295</b>, 85–92.</p>","pubmedId":"","doi":""},{"reference":"<p>Pichler,B.J. <i>et al.</i> (2008) Multimodal Imaging Approaches: PET/CT and PET/MRI. In, Semmler,W. and Schwaiger,M. (eds), <i>Molecular Imaging I</i>. Springer, Berlin, Heidelberg, pp. 109–132.</p>","pubmedId":"","doi":""},{"reference":"<p>Pimentel,J.F. <i>et al.</i> (2019) A Large-Scale Study About Quality and Reproducibility of Jupyter Notebooks. In, <i>2019 IEEE/ACM 16th International Conference on Mining Software Repositories (MSR)</i>., pp. 507–517.</p>","pubmedId":"","doi":""},{"reference":"<p>Qiu,D.L. (2023) Jupyter AI, https://github.com/jupyterlab/jupyter-ai.</p>","pubmedId":"","doi":""},{"reference":"<p>Samuel,S. and Mietchen,D. (2024) Computational reproducibility of Jupyter notebooks from biomedical publications. <i>GigaScience</i>, <b>13</b>, giad113.</p>","pubmedId":"","doi":""},{"reference":"<p>Seifert,M. (2015) pytest-asyncio, https://github.com/pytest-dev/pytest-asyncio.</p>","pubmedId":"","doi":""},{"reference":"<p>Senft,R.A. <i>et al.</i> (2023) A biologist’s guide to planning and performing quantitative bioimaging experiments. <i>PLOS Biol.</i>, <b>21</b>, e3002167.</p>","pubmedId":"","doi":""},{"reference":"<p>Sofroniew,N. <i>et al.</i> (2025) napari: a multi-dimensional image viewer for Python, https://zenodo.org/doi/10.5281/zenodo.3555620.</p>","pubmedId":"","doi":""},{"reference":"<p>Xiang,W. <i>et al.</i> (2018) Correlative live and super-resolution imaging reveals the dynamic structure of replication domains. <i>J. Cell Biol.</i>, <b>217</b>, 1973–1984.</p>","pubmedId":"","doi":""}],"title":"<p>JuNkIE-CLImax: exploring multidimensional images in notebooks and the terminal</p>","reviews":[{"reviewer":{"displayName":"Ignacio Arganda-Carreras"},"openAcknowledgement":true,"status":{"submitted":true}}],"curatorReviews":[]},{"id":"55359ac7-e618-470e-a723-0426f0fc9537","decision":"revise","abstract":"<p>Modern microscopy generates multidimensional images. Graphical user interfaces allow visualization of multidimensional images, but image exploration is significantly harder in text-based environments. These include Jupyter notebooks, popular for the distribution of data analysis pipelines; and the terminal, often the only user interface available when accessing images in remote servers. We developed JuNkIE-CLImax, a pair of multidimensional image explorers designed to work in Jupyter notebooks and the terminal, respectively. JuNkIE-CLImax are written in Python, using Rust extensions to optimize performance; they are platform agnostic; and they provide application programming interfaces that enable integration into complex image visualization and analysis pipelines.</p>","acknowledgements":"<p>We are grateful to Negar Balaghi, Alexandra Korolov and Willow Peterson for comments on the manuscript. </p>","authors":[{"affiliations":["University of Toronto, Toronto, ON, CA","University of Toronto, Toronto, ON, CA","University of Toronto, Toronto, ON, CA","Hospital for Sick Children, Toronto, ON, CA"],"departments":["Institute of Biomedical Engineering","Ted Rogers Centre for Heart Research, Translational Biology and Engineering Program","Department of Cell and Systems Biology","Developmental and Stem Cell Biology Program"],"credit":["conceptualization","fundingAcquisition","methodology","project","resources","software","supervision","validation","visualization","writing_originalDraft","writing_reviewEditing","investigation"],"email":"rodrigo.fernandez.gonzalez@utoronto.ca","firstName":"Rodrigo","lastName":"Fernandez-Gonzalez","submittingAuthor":true,"correspondingAuthor":true,"equalContribution":false,"WBId":null,"orcid":"0000-0003-0770-744X"},{"affiliations":["University of Toronto, Toronto, ON, CA","University of Toronto, Toronto, ON, CA"],"departments":["Institute of Biomedical Engineering","Ted Rogers Centre for Heart Research, Translational Biology and Engineering Program"],"credit":["software","writing_reviewEditing"],"email":"raymond.hawkins@mail.utoronto.ca","firstName":"Raymond","lastName":"Hawkins","submittingAuthor":false,"correspondingAuthor":false,"equalContribution":false,"WBId":null,"orcid":null}],"awards":[],"conflictsOfInterest":"<p>The authors declare that there are no conflicts of interest present.</p>","dataTable":null,"extendedData":[],"funding":"<p>This work was supported by the Natural Sciences and Engineering Research Council of Canada (418438-13), the Canadian Institutes of Health Research (186188), the Canada Foundation for Innovation (30279), the Translational Biology and Engineering Program of the Ted Rogers Centre for Heart Research., and the University of Toronto EMHSeed Program. RFG is the Canada Research Chair in Quantitative Cell Biology and Morphogenesis.</p>","image":{"url":"https://portal.micropublication.org/uploads/e51ebf218e7555933af8a13dcfbec3be.png"},"imageCaption":"<p><b>(A)</b> JuNkIE (top) and CLImax (bottom) user interfaces displaying multidimensional images in a notebook and the terminal, respectively. JuNkIE-CLImax provide widgets to browse different image dimensions; expose multiple colormaps, including scientific colormaps; and conduct simple image operations, including rotation, flipping, zooming, reslicing and contrast adjustment. <b>(B)</b> Character-based image rendering. Sample image (left) and corresponding rich Style strings to render the image in the terminal (right), using a half-block character to display each pair of vertically-adjacent pixels. For instance, the Style parsed from \"<i>rgb(255,0,0) on rgb(0,255,255)</i>\", when associated with the half-block character, renders a red half-block on a cyan background, representing a cyan pixel in the top row and a red pixel in the bottom row, respectively<i>. </i>End-of-line characters (\"\\n\") indicate the ends of pairs of rows.</p>","imageTitle":"<p><b>JuNkIE-CLImax: multidimensional image explorers for notebooks and the terminal</b></p>","methods":"<p></p>","reagents":"<p></p>","patternDescription":"<p>Quantitative image analysis of microscopy datasets is a central tool in modern cell and developmental biology (Meijering and Cappellen, 2007; Senft et al., 2023). The advent of machine learning methods has established Python as the <i>de facto</i> standard for the analysis of biomedical images (Jacquemet, 2021; Morgado et al., 2024). Jupyter notebooks (Granger and Pérez, 2021) provide a beginner-friendly environment that enables prototyping and distribution&nbsp; of complex image processing pipelines (von Chamier et al., 2021). Platforms such as Google Colab or DigitalOcean provide free access to high-end computing capacity to execute notebooks, thus \"democratizing\" the use of resources that would otherwise be too costly. Notebooks facilitate data exploration and increase the reproducibility of data processing pipelines (Kluyver et al., 2016; Pimentel et al., 2019; Samuel and Mietchen, 2024). The leading position of notebooks for data analysis is cemented by the recent availability of large language models within notebooks (Qiu, 2023), which further facilitates development, debugging and execution of image processing and quantification routines. Thus, notebooks are a central element in the analysis of biomedical image data.</p><p>Both biological and medical imaging generate multidimensional data. Confocal and light sheet microscopies, for instance, allow collection of three-dimensional stacks (X, Y, Z) of different fluorescent reporters (wavelength), over the duration of a biological process (time). Multimodality imaging, such as correlative confocal and electron microscopies (Casares-Arias et al., 2021), confocal and super-resolution (Xiang et al., 2018), or the combination of anatomical and functional data in medical imaging (Pichler et al., 2008), introduces a sixth imaging dimension. Processing and analysis of multidimensional image datasets often requires image exploration at many stages in which rapid visualization and browsing are key steps. Two-dimensional images can be easily displayed in notebooks, <i>e.g.</i> with <i>matplotlib</i> (Hunter, 2007). However, few tools exist to display, browse and interact with multidimensional images in a notebook (Haase, 2021), and some of the available options provide complex user interfaces and functionality that prevent light-weight, inline multidimensional image browsing (Sofroniew et al., 2025).</p><p>Microscopy images are generally archived in remote backup servers. The advent of cloud-based storage services has only increased this trend. &nbsp;Remote and cloud-based servers often do not provide a graphical user interface, but simply a terminal-based, command line interface. Terminals can display text-based information about the images (file name, size, date, etc.), but do not allow image visualization. The lack of tools for image display on the terminal makes it hard to select images either for further processing or to generate figures for publication.</p><p>Here we introduce JuNkIE-CLImax, a pair of open source tools (https://bitbucket.org/rfg_lab/junkie and https://bitbucket.org/rfg_lab/climax) for the display and interactive visualization of multidimensional microscopy images in environments traditionally considered to be document or text-based. JuNkIE is a JUpyter NotebooK Image Explorer that enables the opening, display and simple manipulation of multidimensional images in Jupyter notebooks. CLImax, a Command Line IMAge eXplorer, allows users to open, visualize and browse multidimensional images on the terminal, using character-based strategies for image rendering. </p><p></p><p>JuNkIE-CLImax: multidimensional image explorers</p><p>JuNkIE-CLImax can load multidimensional images in the multi-page TIFF format often found in microscopy (Besson et al., 2019), as well as images stored in the increasingly popular <i>zarr</i> array format (Miles, 2015). JuNkIE-CLImax can also import file sequences that represent different dimensions (<i>e.g.</i> time or wavelength) of a multidimensional image. Internally, images are stored using <i>numpy</i>, a package for numerical computation, and its <i>ndarray</i> data structure to represent multidimensional arrays (Harris et al., 2020). JuNkIE-CLImax display a two-dimensional view of a multidimensional image (Fig. 1A). Both packages provide sliders to select a specific Z-plane, time point and channel from the multidimensional image stored in memory, using both mouse and keyboard-based interactions. JuNkIE-CLImax continuously update the displayed image in real time in response to user input. To enable use in settings with reduced compute power (<i>e.g.</i> remote storage servers), it is possible to disable the continuous update of the display, such that updates only occur when the user interaction is completed (<i>e.g.</i> when the mouse button is released, but not while the mouse is dragged). XY, XZ or YZ sectioning planes can be selected. Additionally, JuNkIE-CLImax provide functionality for simple image manipulation. This includes rotation and flipping (both horizontal and vertical), colormap selection and inversion (including all the colormaps available in <i>matplotlib</i> (Crameri et al., 2020; Crameri, 2023)), and both manual and automated contrast adjustment.</p><p></p><p><b><i>JuNkIE</i></b></p><p>JuNkIE displays images using the <i>Figure</i> class in <i>matplotlib</i>. A <i>matplotlib</i> <i>Figure</i> can hold different plot elements, including images. The <i>matplotlib</i> <i>Figure</i> provides a toolbar with options to pan, zoom in and out, reset the view, or save a snapshot (Fig. 1A, top).</p><p>JuNkIE provides a simple application programming interface (API). Using the JuNkIE API it is possible to open images from disk, by providing a file or folder path, or to view volumetric information already loaded as an <i>ndarray</i>. Substrings can be used to distinguish which files in an image sequence store specific dimensions (<i>e.g.</i> different image channels). Lastly, the colormap used to initially display an image, as well as the size of the figure can be used as input parameters when invoking JuNkIE.&nbsp;&nbsp;&nbsp;&nbsp;</p><p>JuNkIE is distributed with a test suite using <i>pytest</i> (Krekel et al., 2004) and the <i>nbval</i> plugin for notebook-based testing (Cortes-Ortuno et al., 2016), with code coverage over 90%.</p><p></p><p><b><i>CLImax</i></b></p><p>To display images on the terminal, we created a character-based image renderer. The image renderer uses <i>rich</i>, a Python package for text formatting that allows the use of coloured characters in the terminal (McGugan, 2019; Burns, 2022). Our image renderer takes a two-dimensional <i>ndarray</i> as its input, and produces a sequence of <i>rich</i> Segments, each consisting of a character and some formatting (a <i>Style</i>), punctuated by end-of-line characters at the end of each image row (Fig. 1B). <i>rich Styles</i> determine the colours used to display a character and its background. Colours are defined by the corresponding red, green and blue (rgb) components, specified as a string. Initially, we rendered each pixel using a space character (' '), assigning the pixel value as the background colour and no foreground colour. Because characters on the terminal are rectangular (elongated along the vertical axis), we rendered each image column twice to obtain square pixels. As a consequence, image rendering was relatively slow, requiring 380±23 ms (mean±standard deviation) to render a 512x672 pixel image on an Apple M3 Max equipped with 48 GB of RAM.</p><p>To optimize image rendering, we first reduced the number of terminal characters necessary to display a pixel. We took advantage of the half-block character ('▄') to visualize pairs of vertically-adjacent pixels (same column, consecutive rows) with a single terminal character (Fig. 1B). For each pair of pixels, we rendered the bottom pixel by assigning its value as the foreground colour of a half-block character, and the top pixel by assigning its value as the background colour of the same half-block character (Fig. 1B). This approach allowed us to display each pixel with half a character, in contrast to the previous method, which required two characters per pixel. We further accelerated rendering by creating a <i>Style</i> cache that used a Python dictionary to store the <i>rich</i> <i>Styles</i> corresponding to parsed colour-strings. After these optimizations, rendering speed increased by 57% (163±13 ms/image) and memory consumption decreased by a factor of four.</p><p>To further speed up image display, we implemented the hot-loop of the renderer in Rust (Matsakis and Klock II, 2014). The Rust code implements a helper function with two inputs, a two-dimensional image, and a colour lookup table that contains the string representation of each of the colours available in the current colormap. The helper function then scans the image columns, two rows at a time, generating the <i>Style</i> string for the character that will display a pair of vertically-adjacent pixels. We parallelized the scan over the image columns using the Rust crate <i>rayon</i> (Matsakis and Stone, 2014) to create a parallel iterator. Overall, Rust-based image rendering was 11% faster (146±13 ms/image) than our fastest Python implementation.</p><p>We designed the CLImax user interface with <i>textual</i> (McGugan, 2021) (Fig. 1A, bottom). <i>textual</i> is a Python package for the development of user interfaces and applications for the terminal. <i>textual</i> provides different widgets (<i>e.g.</i> buttons, dropdown boxes, text labels, etc.). We created a new <i>ImagePanel</i> widget that displays an image using the character-based renderer described above. <i>textual</i> apps provide a command palette that includes options to change the theme used to display the application, save a screenshot, or show a help panel. In addition, CLImax provides options to open a new image, zoom in or out, display the image with bilinear interpolation (particularly useful when zooming in/out), or save the current display.</p><p>CLImax can be invoked from the command line with different options. Similar to the JuNkIE API, the CLImax command line parameters enable image selection and substring and colour map specification, as well as initial zoom level, particularly important given that image rendering in the terminal is computationally intensive, with a cost that increases with the number of pixels to be rendered.</p><p>CLImax is also tested with <i>pytest</i>, using the <i>asyncio</i> plugin (Seifert, 2015) to test asynchronous user interaction. CLImax tests provide code coverage greater than 90%.</p>","references":[{"reference":"<p>Besson,S. <i>et al.</i> (2019) Bringing Open Data to Whole Slide Imaging. In, Reyes-Aldasoro,C.C. <i>et al.</i> (eds), <i>Digital Pathology</i>. Springer International Publishing, Cham, pp. 3–10.</p>","pubmedId":"","doi":""},{"reference":"<p>Burns,D. (2022) rich-pixels, https://github.com/darrenburns/rich-pixels.</p>","pubmedId":"","doi":""},{"reference":"<p>Casares-Arias,J. <i>et al.</i> (2021) Correlative confocal and scanning electron microscopy of cultured cells without using dedicated equipment. <i>STAR Protoc.</i>, <b>2</b>, 100727.</p>","pubmedId":"","doi":""},{"reference":"<p>von Chamier,L. <i>et al.</i> (2021) Democratising deep learning for microscopy with ZeroCostDL4Mic. <i>Nat Commun</i>, <b>12</b>, 2276.</p>","pubmedId":"","doi":""},{"reference":"<p>Cortes-Ortuno,D. <i>et al.</i> (2016) nbval, https://github.com/computationalmodelling/nbval.</p>","pubmedId":"","doi":""},{"reference":"<p>Crameri,F. (2023) Scientific colour maps, https://zenodo.org/records/8409685.</p>","pubmedId":"","doi":""},{"reference":"<p>Crameri,F. <i>et al.</i> (2020) The misuse of colour in science communication. <i>Nat. Commun.</i>, <b>11</b>, 5444.</p>","pubmedId":"","doi":""},{"reference":"<p>Granger,B.E. and Pérez,F. (2021) Jupyter: Thinking and Storytelling With Code and Data. <i>Comput. Sci. Eng.</i>, <b>23</b>, 7–14.</p>","pubmedId":"","doi":""},{"reference":"<p>Haase,R. (2021) stackview, https://github.com/haesleinhuepf/stackview.</p>","pubmedId":"","doi":""},{"reference":"<p>Harris,C.R. <i>et al.</i> (2020) Array programming with NumPy. <i>Nature</i>, <b>585</b>, 357–362.</p>","pubmedId":"","doi":""},{"reference":"<p>Hunter,J.D. (2007) Matplotlib: A 2D Graphics Environment. <i>Comput. Sci. Eng.</i>, <b>9</b>, 90–95.</p>","pubmedId":"","doi":""},{"reference":"<p>Jacquemet,G. (2021) Deep learning to analyse microscopy images. <i>The Biochemist</i>, <b>43</b>, 60–64.</p>","pubmedId":"","doi":""},{"reference":"<p>Kluyver,T. <i>et al.</i> (2016) Jupyter Notebooks – a publishing format for reproducible computational workflows.</p>","pubmedId":"","doi":""},{"reference":"<p>Krekel,H. <i>et al.</i> (2004) pytest, https://github.com/pytest-dev/pytest.</p>","pubmedId":"","doi":""},{"reference":"<p>Matsakis,N.D. and Klock II,F.S. (2014) The rust language. In, <i>ACM SIGAda Ada Letters</i>. ACM, pp. 103–104.</p>","pubmedId":"","doi":""},{"reference":"<p>Matsakis,N.D. and Stone,J. (2014) Rayon: A data parallelism library for Rust, https://github.com/rayon-rs/rayon/.</p>","pubmedId":"","doi":""},{"reference":"<p>McGugan,W. (2019) rich, https://github.com/Textualize/rich.</p>","pubmedId":"","doi":""},{"reference":"<p>McGugan,W. (2021) Textual, https://textual.textualize.io/.</p>","pubmedId":"","doi":""},{"reference":"<p>Meijering,E. and Cappellen,G. van (2007) Quantitative Biological Image Analysis. In, Shorte,S.L. and Frischknecht,F. (eds), <i>Imaging Cellular and Molecular Biological Functions</i>. Springer, Berlin, Heidelberg, pp. 45–70.</p>","pubmedId":"","doi":""},{"reference":"<p>Miles,A. (2015) zarr, https://github.com/zarr-developers/zarr-python.</p>","pubmedId":"","doi":""},{"reference":"<p>Morgado,L. <i>et al.</i> (2024) The rise of data-driven microscopy powered by machine learning. <i>J. Microsc.</i>, <b>295</b>, 85–92.</p>","pubmedId":"","doi":""},{"reference":"<p>Pichler,B.J. <i>et al.</i> (2008) Multimodal Imaging Approaches: PET/CT and PET/MRI. In, Semmler,W. and Schwaiger,M. (eds), <i>Molecular Imaging I</i>. Springer, Berlin, Heidelberg, pp. 109–132.</p>","pubmedId":"","doi":""},{"reference":"<p>Pimentel,J.F. <i>et al.</i> (2019) A Large-Scale Study About Quality and Reproducibility of Jupyter Notebooks. In, <i>2019 IEEE/ACM 16th International Conference on Mining Software Repositories (MSR)</i>., pp. 507–517.</p>","pubmedId":"","doi":""},{"reference":"<p>Qiu,D.L. (2023) Jupyter AI, https://github.com/jupyterlab/jupyter-ai.</p>","pubmedId":"","doi":""},{"reference":"<p>Samuel,S. and Mietchen,D. (2024) Computational reproducibility of Jupyter notebooks from biomedical publications. <i>GigaScience</i>, <b>13</b>, giad113.</p>","pubmedId":"","doi":""},{"reference":"<p>Seifert,M. (2015) pytest-asyncio, https://github.com/pytest-dev/pytest-asyncio.</p>","pubmedId":"","doi":""},{"reference":"<p>Senft,R.A. <i>et al.</i> (2023) A biologist’s guide to planning and performing quantitative bioimaging experiments. <i>PLOS Biol.</i>, <b>21</b>, e3002167.</p>","pubmedId":"","doi":""},{"reference":"<p>Sofroniew,N. <i>et al.</i> (2025) napari: a multi-dimensional image viewer for Python, https://zenodo.org/doi/10.5281/zenodo.3555620.</p>","pubmedId":"","doi":""},{"reference":"<p>Xiang,W. <i>et al.</i> (2018) Correlative live and super-resolution imaging reveals the dynamic structure of replication domains. <i>J. Cell Biol.</i>, <b>217</b>, 1973–1984.</p>","pubmedId":"","doi":""}],"title":"<p>JuNkIE-CLImax: exploring multidimensional images in notebooks and the terminal</p>","reviews":[{"reviewer":{"displayName":"Ignacio Arganda-Carreras"},"openAcknowledgement":true,"status":{"submitted":true}}],"curatorReviews":[]},{"id":"8c2ddd9e-0c46-4bc1-9cbd-94e54d06b32d","decision":"accept","abstract":"<p>Modern microscopy generates multidimensional images. Graphical user interfaces allow visualization of multidimensional images, but image exploration is significantly harder in text-based environments. These include Jupyter notebooks, popular for the distribution of data analysis pipelines; and the terminal, often the only user interface available when accessing images in remote servers. We developed JuNkIE-CLImax, a pair of multidimensional image explorers designed to work in Jupyter notebooks and the terminal, respectively. JuNkIE-CLImax are written in Python, using Rust extensions to optimize performance; they are platform agnostic; and they provide application programming interfaces that enable integration into complex image visualization and analysis pipelines.</p>","acknowledgements":"<p>We are grateful to Negar Balaghi, Alexandra Korolov and Willow Peterson for comments on the manuscript. </p>","authors":[{"affiliations":["University of Toronto, Toronto, ON, CA","University of Toronto, Toronto, ON, CA","University of Toronto, Toronto, ON, CA","Hospital for Sick Children, Toronto, ON, CA"],"departments":["Institute of Biomedical Engineering","Ted Rogers Centre for Heart Research, Translational Biology and Engineering Program","Department of Cell and Systems Biology","Developmental and Stem Cell Biology Program"],"credit":["conceptualization","fundingAcquisition","methodology","project","resources","software","supervision","validation","visualization","writing_originalDraft","writing_reviewEditing","investigation"],"email":"rodrigo.fernandez.gonzalez@utoronto.ca","firstName":"Rodrigo","lastName":"Fernandez-Gonzalez","submittingAuthor":true,"correspondingAuthor":true,"equalContribution":false,"WBId":null,"orcid":"0000-0003-0770-744X"},{"affiliations":["University of Toronto, Toronto, ON, CA","University of Toronto, Toronto, ON, CA"],"departments":["Institute of Biomedical Engineering","Ted Rogers Centre for Heart Research, Translational Biology and Engineering Program"],"credit":["software","writing_reviewEditing"],"email":"raymond.hawkins@mail.utoronto.ca","firstName":"Raymond","lastName":"Hawkins","submittingAuthor":false,"correspondingAuthor":false,"equalContribution":false,"WBId":null,"orcid":null}],"awards":[],"conflictsOfInterest":"<p>The authors declare that there are no conflicts of interest present.</p>","dataTable":null,"extendedData":[],"funding":"<p>This work was supported by the Natural Sciences and Engineering Research Council of Canada (418438-13), the Canadian Institutes of Health Research (186188), the Canada Foundation for Innovation (30279), the Translational Biology and Engineering Program of the Ted Rogers Centre for Heart Research., and the University of Toronto EMHSeed Program. RFG is the Canada Research Chair in Quantitative Cell Biology and Morphogenesis.</p>","image":{"url":"https://portal.micropublication.org/uploads/e51ebf218e7555933af8a13dcfbec3be.png"},"imageCaption":"<p><b>(A)</b> JuNkIE (top) and CLImax (bottom) user interfaces displaying multidimensional images in a notebook and the terminal, respectively. JuNkIE-CLImax provide widgets to browse different image dimensions; expose multiple colormaps, including scientific colormaps; and conduct simple image operations, including rotation, flipping, zooming, reslicing and contrast adjustment. <b>(B)</b> Character-based image rendering. Sample image (left) and corresponding rich Style strings to render the image in the terminal (right), using a half-block character to display each pair of vertically-adjacent pixels. For instance, the Style parsed from \"<i>rgb(255,0,0) on rgb(0,255,255)</i>\", when associated with the half-block character, renders a red half-block on a cyan background, representing a cyan pixel in the top row and a red pixel in the bottom row, respectively<i>. </i>End-of-line characters (\"\\n\") indicate the ends of pairs of rows.</p>","imageTitle":"<p><b>JuNkIE-CLImax: multidimensional image explorers for notebooks and the terminal</b></p>","methods":"<p></p>","reagents":"<p></p>","patternDescription":"<p>Quantitative image analysis of microscopy datasets is a central tool in modern cell and developmental biology (Meijering and Cappellen, 2007; Senft et al., 2023). The advent of machine learning methods has established Python as the <i>de facto</i> standard for the analysis of biomedical images (Jacquemet, 2021; Morgado et al., 2024). Jupyter notebooks (Granger and Pérez, 2021) provide a beginner-friendly environment that enables prototyping and distribution&nbsp; of complex image processing pipelines (von Chamier et al., 2021). Platforms such as Google Colab or DigitalOcean provide free access to high-end computing capacity to execute notebooks, thus \"democratizing\" the use of resources that would otherwise be too costly. Notebooks facilitate data exploration and increase the reproducibility of data processing pipelines (Kluyver et al., 2016; Pimentel et al., 2019; Samuel and Mietchen, 2024). The leading position of notebooks for data analysis is cemented by the recent availability of large language models within notebooks (Qiu, 2023), which further facilitates development, debugging and execution of image processing and quantification routines. Thus, notebooks are a central element in the analysis of biomedical image data.</p><p>Both biological and medical imaging generate multidimensional data. Confocal and light sheet microscopies, for instance, allow collection of three-dimensional stacks (X, Y, Z) of different fluorescent reporters (wavelength), over the duration of a biological process (time). Multimodality imaging, such as correlative confocal and electron microscopies (Casares-Arias et al., 2021), confocal and super-resolution (Xiang et al., 2018), or the combination of anatomical and functional data in medical imaging (Pichler et al., 2008), introduces a sixth imaging dimension. Processing and analysis of multidimensional image datasets often requires image exploration at many stages in which rapid visualization and browsing are key steps. Two-dimensional images can be easily displayed in notebooks, <i>e.g.</i> with <i>matplotlib</i> (Hunter, 2007). However, few tools exist to display, browse and interact with multidimensional images in a notebook (Haase, 2021), and some of the available options provide complex user interfaces and functionality that prevent light-weight, inline multidimensional image browsing (Sofroniew et al., 2025).</p><p>Microscopy images are generally archived in remote backup servers. The advent of cloud-based storage services has only increased this trend. &nbsp;Remote and cloud-based servers often do not provide a graphical user interface, but simply a terminal-based, command line interface. Terminals can display text-based information about the images (file name, size, date, etc.), but do not allow image visualization. The lack of tools for image display on the terminal makes it hard to select images either for further processing or to generate figures for publication.</p><p>Here we introduce JuNkIE-CLImax, a pair of open source tools (https://bitbucket.org/rfg_lab/junkie and https://bitbucket.org/rfg_lab/climax) for the display and interactive visualization of multidimensional microscopy images in environments traditionally considered to be document or text-based. JuNkIE is a JUpyter NotebooK Image Explorer that enables the opening, display and simple manipulation of multidimensional images in Jupyter notebooks. CLImax, a Command Line IMAge eXplorer, allows users to open, visualize and browse multidimensional images on the terminal, using character-based strategies for image rendering. </p><p></p><p>JuNkIE-CLImax: multidimensional image explorers</p><p>JuNkIE-CLImax can load multidimensional images in the multi-page TIFF format often found in microscopy (Besson et al., 2019), as well as images stored in the increasingly popular <i>zarr</i> array format (Miles, 2015). JuNkIE-CLImax can also import file sequences that represent different dimensions (<i>e.g.</i> time or wavelength) of a multidimensional image. Internally, images are stored using <i>numpy</i>, a package for numerical computation, and its <i>ndarray</i> data structure to represent multidimensional arrays (Harris et al., 2020). JuNkIE-CLImax display a two-dimensional view of a multidimensional image (Fig. 1A). Both packages provide sliders to select a specific Z-plane, time point and channel from the multidimensional image stored in memory, using both mouse and keyboard-based interactions. JuNkIE-CLImax continuously update the displayed image in real time in response to user input. To enable use in settings with reduced compute power (<i>e.g.</i> remote storage servers), it is possible to disable the continuous update of the display, such that updates only occur when the user interaction is completed (<i>e.g.</i> when the mouse button is released, but not while the mouse is dragged). XY, XZ or YZ sectioning planes can be selected. Additionally, JuNkIE-CLImax provide functionality for simple image manipulation. This includes rotation and flipping (both horizontal and vertical), colormap selection and inversion (including all the colormaps available in <i>matplotlib</i> (Crameri et al., 2020; Crameri, 2023)), and both manual and automated contrast adjustment.</p><p></p><p><b><i>JuNkIE</i></b></p><p>JuNkIE displays images using the <i>Figure</i> class in <i>matplotlib</i>. A <i>matplotlib</i> <i>Figure</i> can hold different plot elements, including images. The <i>matplotlib</i> <i>Figure</i> provides a toolbar with options to pan, zoom in and out, reset the view, or save a snapshot (Fig. 1A, top).</p><p>JuNkIE provides a simple application programming interface (API). Using the JuNkIE API it is possible to open images from disk, by providing a file or folder path, or to view volumetric information already loaded as an <i>ndarray</i>. Substrings can be used to distinguish which files in an image sequence store specific dimensions (<i>e.g.</i> different image channels). Lastly, the colormap used to initially display an image, as well as the size of the figure can be used as input parameters when invoking JuNkIE.&nbsp;&nbsp;&nbsp;&nbsp;</p><p>JuNkIE is distributed with a test suite using <i>pytest</i> (Krekel et al., 2004) and the <i>nbval</i> plugin for notebook-based testing (Cortes-Ortuno et al., 2016), with code coverage over 90%.</p><p></p><p><b><i>CLImax</i></b></p><p>To display images on the terminal, we created a character-based image renderer. The image renderer uses <i>rich</i>, a Python package for text formatting that allows the use of coloured characters in the terminal (McGugan, 2019; Burns, 2022). Our image renderer takes a two-dimensional <i>ndarray</i> as its input, and produces a sequence of <i>rich</i> Segments, each consisting of a character and some formatting (a <i>Style</i>), punctuated by end-of-line characters at the end of each image row (Fig. 1B). <i>rich Styles</i> determine the colours used to display a character and its background. Colours are defined by the corresponding red, green and blue (rgb) components, specified as a string. Initially, we rendered each pixel using a space character (' '), assigning the pixel value as the background colour and no foreground colour. Because characters on the terminal are rectangular (elongated along the vertical axis), we rendered each image column twice to obtain square pixels. As a consequence, image rendering was relatively slow, requiring 380±23 ms (mean±standard deviation) to render a 512x672 pixel image on an Apple M3 Max equipped with 48 GB of RAM.</p><p>To optimize image rendering, we first reduced the number of terminal characters necessary to display a pixel. We took advantage of the half-block character ('▄') to visualize pairs of vertically-adjacent pixels (same column, consecutive rows) with a single terminal character (Fig. 1B). For each pair of pixels, we rendered the bottom pixel by assigning its value as the foreground colour of a half-block character, and the top pixel by assigning its value as the background colour of the same half-block character (Fig. 1B). This approach allowed us to display each pixel with half a character, in contrast to the previous method, which required two characters per pixel. We further accelerated rendering by creating a <i>Style</i> cache that used a Python dictionary to store the <i>rich</i> <i>Styles</i> corresponding to parsed colour-strings. After these optimizations, rendering speed increased by 57% (163±13 ms/image) and memory consumption decreased by a factor of four.</p><p>To further speed up image display, we implemented the hot-loop of the renderer in Rust (Matsakis and Klock II, 2014). The Rust code implements a helper function with two inputs, a two-dimensional image, and a colour lookup table that contains the string representation of each of the colours available in the current colormap. The helper function then scans the image columns, two rows at a time, generating the <i>Style</i> string for the character that will display a pair of vertically-adjacent pixels. We parallelized the scan over the image columns using the Rust crate <i>rayon</i> (Matsakis and Stone, 2014) to create a parallel iterator. Overall, Rust-based image rendering was 11% faster (146±13 ms/image) than our fastest Python implementation.</p><p>We designed the CLImax user interface with <i>textual</i> (McGugan, 2021) (Fig. 1A, bottom). <i>textual</i> is a Python package for the development of user interfaces and applications for the terminal. <i>textual</i> provides different widgets (<i>e.g.</i> buttons, dropdown boxes, text labels, etc.). We created a new <i>ImagePanel</i> widget that displays an image using the character-based renderer described above. <i>textual</i> apps provide a command palette that includes options to change the theme used to display the application, save a screenshot, or show a help panel. In addition, CLImax provides options to open a new image, zoom in or out, display the image with bilinear interpolation (particularly useful when zooming in/out), or save the current display.</p><p>CLImax can be invoked from the command line with different options. Similar to the JuNkIE API, the CLImax command line parameters enable image selection and substring and colour map specification, as well as initial zoom level, particularly important given that image rendering in the terminal is computationally intensive, with a cost that increases with the number of pixels to be rendered.</p><p>CLImax is also tested with <i>pytest</i>, using the <i>asyncio</i> plugin (Seifert, 2015) to test asynchronous user interaction. CLImax tests provide code coverage greater than 90%.</p>","references":[{"reference":"<p>Besson,S. <i>et al.</i> (2019) Bringing Open Data to Whole Slide Imaging. In, Reyes-Aldasoro,C.C. <i>et al.</i> (eds), <i>Digital Pathology</i>. Springer International Publishing, Cham, pp. 3–10.</p>","pubmedId":"","doi":""},{"reference":"<p>Burns,D. (2022) rich-pixels, https://github.com/darrenburns/rich-pixels.</p>","pubmedId":"","doi":""},{"reference":"<p>Casares-Arias,J. <i>et al.</i> (2021) Correlative confocal and scanning electron microscopy of cultured cells without using dedicated equipment. <i>STAR Protoc.</i>, <b>2</b>, 100727.</p>","pubmedId":"","doi":""},{"reference":"<p>von Chamier,L. <i>et al.</i> (2021) Democratising deep learning for microscopy with ZeroCostDL4Mic. <i>Nat Commun</i>, <b>12</b>, 2276.</p>","pubmedId":"","doi":""},{"reference":"<p>Cortes-Ortuno,D. <i>et al.</i> (2016) nbval, https://github.com/computationalmodelling/nbval.</p>","pubmedId":"","doi":""},{"reference":"<p>Crameri,F. (2023) Scientific colour maps, https://zenodo.org/records/8409685.</p>","pubmedId":"","doi":""},{"reference":"<p>Crameri,F. <i>et al.</i> (2020) The misuse of colour in science communication. <i>Nat. Commun.</i>, <b>11</b>, 5444.</p>","pubmedId":"","doi":""},{"reference":"<p>Granger,B.E. and Pérez,F. (2021) Jupyter: Thinking and Storytelling With Code and Data. <i>Comput. Sci. Eng.</i>, <b>23</b>, 7–14.</p>","pubmedId":"","doi":""},{"reference":"<p>Haase,R. (2021) stackview, https://github.com/haesleinhuepf/stackview.</p>","pubmedId":"","doi":""},{"reference":"<p>Harris,C.R. <i>et al.</i> (2020) Array programming with NumPy. <i>Nature</i>, <b>585</b>, 357–362.</p>","pubmedId":"","doi":""},{"reference":"<p>Hunter,J.D. (2007) Matplotlib: A 2D Graphics Environment. <i>Comput. Sci. Eng.</i>, <b>9</b>, 90–95.</p>","pubmedId":"","doi":""},{"reference":"<p>Jacquemet,G. (2021) Deep learning to analyse microscopy images. <i>The Biochemist</i>, <b>43</b>, 60–64.</p>","pubmedId":"","doi":""},{"reference":"<p>Kluyver,T. <i>et al.</i> (2016) Jupyter Notebooks – a publishing format for reproducible computational workflows.</p>","pubmedId":"","doi":""},{"reference":"<p>Krekel,H. <i>et al.</i> (2004) pytest, https://github.com/pytest-dev/pytest.</p>","pubmedId":"","doi":""},{"reference":"<p>Matsakis,N.D. and Klock II,F.S. (2014) The rust language. In, <i>ACM SIGAda Ada Letters</i>. ACM, pp. 103–104.</p>","pubmedId":"","doi":""},{"reference":"<p>Matsakis,N.D. and Stone,J. (2014) Rayon: A data parallelism library for Rust, https://github.com/rayon-rs/rayon/.</p>","pubmedId":"","doi":""},{"reference":"<p>McGugan,W. (2019) rich, https://github.com/Textualize/rich.</p>","pubmedId":"","doi":""},{"reference":"<p>McGugan,W. (2021) Textual, https://textual.textualize.io/.</p>","pubmedId":"","doi":""},{"reference":"<p>Meijering,E. and Cappellen,G. van (2007) Quantitative Biological Image Analysis. In, Shorte,S.L. and Frischknecht,F. (eds), <i>Imaging Cellular and Molecular Biological Functions</i>. Springer, Berlin, Heidelberg, pp. 45–70.</p>","pubmedId":"","doi":""},{"reference":"<p>Miles,A. (2015) zarr, https://github.com/zarr-developers/zarr-python.</p>","pubmedId":"","doi":""},{"reference":"<p>Morgado,L. <i>et al.</i> (2024) The rise of data-driven microscopy powered by machine learning. <i>J. Microsc.</i>, <b>295</b>, 85–92.</p>","pubmedId":"","doi":""},{"reference":"<p>Pichler,B.J. <i>et al.</i> (2008) Multimodal Imaging Approaches: PET/CT and PET/MRI. In, Semmler,W. and Schwaiger,M. (eds), <i>Molecular Imaging I</i>. Springer, Berlin, Heidelberg, pp. 109–132.</p>","pubmedId":"","doi":""},{"reference":"<p>Pimentel,J.F. <i>et al.</i> (2019) A Large-Scale Study About Quality and Reproducibility of Jupyter Notebooks. In, <i>2019 IEEE/ACM 16th International Conference on Mining Software Repositories (MSR)</i>., pp. 507–517.</p>","pubmedId":"","doi":""},{"reference":"<p>Qiu,D.L. (2023) Jupyter AI, https://github.com/jupyterlab/jupyter-ai.</p>","pubmedId":"","doi":""},{"reference":"<p>Samuel,S. and Mietchen,D. (2024) Computational reproducibility of Jupyter notebooks from biomedical publications. <i>GigaScience</i>, <b>13</b>, giad113.</p>","pubmedId":"","doi":""},{"reference":"<p>Seifert,M. (2015) pytest-asyncio, https://github.com/pytest-dev/pytest-asyncio.</p>","pubmedId":"","doi":""},{"reference":"<p>Senft,R.A. <i>et al.</i> (2023) A biologist’s guide to planning and performing quantitative bioimaging experiments. <i>PLOS Biol.</i>, <b>21</b>, e3002167.</p>","pubmedId":"","doi":""},{"reference":"<p>Sofroniew,N. <i>et al.</i> (2025) napari: a multi-dimensional image viewer for Python, https://zenodo.org/doi/10.5281/zenodo.3555620.</p>","pubmedId":"","doi":""},{"reference":"<p>Xiang,W. <i>et al.</i> (2018) Correlative live and super-resolution imaging reveals the dynamic structure of replication domains. <i>J. Cell Biol.</i>, <b>217</b>, 1973–1984.</p>","pubmedId":"","doi":""}],"title":"<p>JuNkIE-CLImax: exploring multidimensional images in notebooks and the terminal</p>","reviews":[{"reviewer":{"displayName":"Ignacio Arganda-Carreras"},"openAcknowledgement":true,"status":{"submitted":true}}],"curatorReviews":[]},{"id":"bbbd1738-cfc3-4fcc-bed0-b3902d82a542","decision":"revise","abstract":"<p>Modern microscopy generates multidimensional images. Graphical user interfaces allow visualization of multidimensional images, but image exploration is significantly harder in text-based environments. These include Jupyter notebooks, popular for the distribution of data analysis pipelines; and the terminal, often the only user interface available when accessing images in remote servers. We developed JuNkIE-CLImax, a pair of multidimensional image explorers designed to work in Jupyter notebooks and the terminal, respectively. JuNkIE-CLImax are written in Python, using Rust extensions to optimize performance; they are platform agnostic; and they provide application programming interfaces that enable integration into complex image visualization and analysis pipelines.</p>","acknowledgements":"<p>We are grateful to Negar Balaghi, Alexandra Korolov and Willow Peterson for comments on the manuscript. </p>","authors":[{"affiliations":["University of Toronto, Toronto, ON, CA","University of Toronto, Toronto, ON, CA","University of Toronto, Toronto, ON, CA","Hospital for Sick Children, Toronto, ON, CA"],"departments":["Institute of Biomedical Engineering","Ted Rogers Centre for Heart Research, Translational Biology and Engineering Program","Department of Cell and Systems Biology","Developmental and Stem Cell Biology Program"],"credit":["conceptualization","fundingAcquisition","methodology","project","resources","software","supervision","validation","visualization","writing_originalDraft","writing_reviewEditing","investigation"],"email":"rodrigo.fernandez.gonzalez@utoronto.ca","firstName":"Rodrigo","lastName":"Fernandez-Gonzalez","submittingAuthor":true,"correspondingAuthor":true,"equalContribution":false,"WBId":null,"orcid":"0000-0003-0770-744X"},{"affiliations":["University of Toronto, Toronto, ON, CA","University of Toronto, Toronto, ON, CA"],"departments":["Institute of Biomedical Engineering","Ted Rogers Centre for Heart Research, Translational Biology and Engineering Program"],"credit":["software","writing_reviewEditing"],"email":"raymond.hawkins@mail.utoronto.ca","firstName":"Raymond","lastName":"Hawkins","submittingAuthor":false,"correspondingAuthor":false,"equalContribution":false,"WBId":null,"orcid":null}],"awards":[],"conflictsOfInterest":"<p>The authors declare that there are no conflicts of interest present.</p>","dataTable":{"url":null},"extendedData":[],"funding":"<p>This work was supported by the Natural Sciences and Engineering Research Council of Canada (418438-13), the Canadian Institutes of Health Research (186188), the Canada Foundation for Innovation (30279), the Translational Biology and Engineering Program of the Ted Rogers Centre for Heart Research., and the University of Toronto EMHSeed Program. RFG is the Canada Research Chair in Quantitative Cell Biology and Morphogenesis.</p>","image":{"url":"https://portal.micropublication.org/uploads/e51ebf218e7555933af8a13dcfbec3be.png"},"imageCaption":"<p><b>(A)</b> JuNkIE (top) and CLImax (bottom) user interfaces displaying multidimensional images in a notebook and the terminal, respectively. JuNkIE-CLImax provide widgets to browse different image dimensions; expose multiple colormaps, including scientific colormaps; and conduct simple image operations, including rotation, flipping, zooming, reslicing and contrast adjustment. <b>(B)</b> Character-based image rendering. Sample image (left) and corresponding <i>rich</i> Style strings to render the image in the terminal (right), using a half-block character to display each pair of vertically-adjacent pixels. For instance, the Style parsed from \"<i>rgb(255,0,0) on rgb(0,255,255)</i>\", when associated with the half-block character, renders a red half-block on a cyan background, representing a cyan pixel in the top row and a red pixel in the bottom row, respectively<i>. </i>End-of-line characters (\"\\n\") indicate the ends of pairs of rows.</p>","imageTitle":"<p><b>JuNkIE-CLImax: multidimensional image explorers for notebooks and the terminal</b></p>","methods":"<p></p>","reagents":"<p></p>","patternDescription":"<p>Quantitative image analysis of microscopy datasets is a central tool in modern cell and developmental biology (Meijering and Cappellen, 2007; Senft et al., 2023). The advent of machine learning methods has established Python as the <i>de facto</i> standard for the analysis of biomedical images (Jacquemet, 2021; Morgado et al., 2024). Jupyter notebooks (Granger and Pérez, 2021) provide a beginner-friendly environment that enables prototyping and distribution&nbsp;of complex image processing pipelines (von Chamier et al., 2021). Platforms such as Google Colab or DigitalOcean provide free access to high-end computing capacity to execute notebooks, thus \"democratizing\" the use of resources that would otherwise be too costly. Notebooks facilitate data exploration and increase the reproducibility of data processing pipelines (Kluyver et al., 2016; Pimentel et al., 2019; Samuel and Mietchen, 2024). The leading position of notebooks for data analysis is cemented by the recent availability of large language models within notebooks (Qiu, 2023), which further facilitates development, debugging and execution of image processing and quantification routines. Thus, notebooks are a central element in the analysis of biomedical image data.</p><p>Both biological and medical imaging generate multidimensional data. Confocal and light sheet microscopies, for instance, allow collection of three-dimensional stacks (X, Y, Z) of different fluorescent reporters (wavelength), over the duration of a biological process (time). Multimodality imaging, such as correlative confocal and electron microscopies (Casares-Arias et al., 2021), confocal and super-resolution (Xiang et al., 2018), or the combination of anatomical and functional data in medical imaging (Pichler et al., 2008), introduces a sixth imaging dimension. Processing and analysis of multidimensional image datasets often requires image exploration at many stages in which rapid visualization and browsing are key steps. Two-dimensional images can be easily displayed in notebooks, <i>e.g.</i> with <i>matplotlib</i> (Hunter, 2007). However, few tools exist to display, browse and interact with multidimensional images in a notebook (Haase, 2021), and some of the available options provide complex user interfaces and functionality that prevent light-weight, inline multidimensional image browsing (Sofroniew et al., 2025).</p><p>Microscopy images are generally archived in remote backup servers. The advent of cloud-based storage services has only increased this trend.&nbsp;Remote and cloud-based servers often do not provide a graphical user interface, but simply a terminal-based, command line interface. Terminals can display text-based information about the images (file name, size, date, etc.), but do not allow image visualization. The lack of tools for image display on the terminal makes it hard to select images either for further processing or to generate figures for publication.</p><p>Here we introduce JuNkIE-CLImax, a pair of open source tools (https://bitbucket.org/rfg_lab/junkie and https://bitbucket.org/rfg_lab/climax) for the display and interactive visualization of multidimensional microscopy images in environments traditionally considered to be document or text-based. JuNkIE is a JUpyter NotebooK Image Explorer that enables the opening, display and simple manipulation of multidimensional images in Jupyter notebooks. CLImax, a Command Line IMAge eXplorer, allows users to open, visualize and browse multidimensional images on the terminal, using character-based strategies for image rendering.</p><p></p><p>JuNkIE-CLImax: multidimensional image explorers</p><p>JuNkIE-CLImax can load multidimensional images in the multi-page TIFF format often found in microscopy (Besson et al., 2019), as well as images stored in the increasingly popular <i>zarr</i> array format (Miles, 2015). JuNkIE-CLImax can also import file sequences that represent different dimensions (<i>e.g.</i> time or wavelength) of a multidimensional image. Internally, images are stored using <i>numpy</i>, a package for numerical computation, and its <i>ndarray</i> data structure to represent multidimensional arrays (Harris et al., 2020). JuNkIE-CLImax display a two-dimensional view of a multidimensional image (Fig. 1A). Both packages provide sliders to select a specific Z-plane, time point and channel from the multidimensional image stored in memory, using both mouse and keyboard-based interactions. JuNkIE-CLImax continuously update the displayed image in real time in response to user input. To enable use in settings with reduced compute power (<i>e.g.</i> remote storage servers), it is possible to disable the continuous update of the display, such that updates only occur when the user interaction is completed (<i>e.g.</i> when the mouse button is released, but not while the mouse is dragged). XY, XZ or YZ sectioning planes can be selected. Additionally, JuNkIE-CLImax provide functionality for simple image manipulation. This includes rotation and flipping (both horizontal and vertical), colormap selection and inversion (including all the colormaps available in <i>matplotlib</i> (Crameri et al., 2020; Crameri, 2023)), and both manual and automated contrast adjustment.</p><p></p><p><b><i>JuNkIE</i></b></p><p>JuNkIE displays images using the <i>Figure</i> class in <i>matplotlib</i>. A <i>matplotlib</i> <i>Figure</i> can hold different plot elements, including images. The <i>matplotlib</i> <i>Figure</i> provides a toolbar with options to pan, zoom in and out, reset the view, or save a snapshot (Fig. 1A, top).</p><p>JuNkIE provides a simple application programming interface (API). Using the JuNkIE API it is possible to open images from disk, by providing a file or folder path, or to view volumetric information already loaded as an <i>ndarray</i>. Substrings can be used to distinguish which files in an image sequence store specific dimensions (<i>e.g.</i> different image channels). Lastly, the colormap used to initially display an image, as well as the size of the figure can be determined with input parameters when invoking JuNkIE.&nbsp;&nbsp;&nbsp;&nbsp;</p><p>JuNkIE is distributed with a test suite using <i>pytest</i> (Krekel et al., 2004) and the <i>nbval</i> plugin for notebook-based testing (Cortes-Ortuno et al., 2016), with code coverage over 90%.</p><p></p><p><b><i>CLImax</i></b></p><p>To display images on the terminal, we created a character-based image renderer. The image renderer uses <i>rich</i>, a Python package for text formatting that allows the use of coloured characters in the terminal (McGugan, 2019; Burns, 2022). Our image renderer takes a two-dimensional <i>ndarray</i> as its input, and produces a sequence of <i>rich</i> Segments, each consisting of a character and some formatting (a <i>Style</i>), punctuated by end-of-line characters at the end of each image row (Fig. 1B). <i>rich Styles</i> determine the colours used to display a character and its background. Colours are defined by the corresponding red, green and blue (rgb) components, specified as a string. Initially, we rendered each pixel using a space character (' '), assigning the pixel value as the background colour and no foreground colour. Because characters on the terminal are rectangular (elongated along the vertical axis), we rendered each image column twice to obtain square pixels. As a consequence, image rendering was relatively slow, requiring 380±23 ms (mean±standard deviation) to render a 512x672 pixel image on an Apple M3 Max equipped with 48 GB of RAM.</p><p>To optimize image rendering, we first reduced the number of terminal characters necessary to display a pixel. We took advantage of the half-block character ('▄') to visualize pairs of vertically-adjacent pixels (same column, consecutive rows) with a single terminal character (Fig. 1B). For each pair of pixels, we rendered the bottom pixel by assigning its value as the foreground colour of a half-block character, and the top pixel by assigning its value as the background colour of the same half-block character (Fig. 1B). This approach allowed us to display each pixel with half a character, in contrast to the previous method, which required two characters per pixel. We further accelerated rendering by creating a <i>Style</i> cache that used a Python dictionary to store the <i>rich</i> <i>Styles</i> corresponding to parsed colour-strings. After these optimizations, rendering speed increased by 57% (163±13 ms/image) and memory consumption decreased by a factor of four.</p><p>To further speed up image display, we implemented the hot-loop of the renderer in Rust (Matsakis and Klock II, 2014). The Rust code implements a helper function with two inputs, a two-dimensional image, and a colour lookup table that contains the string representation of each of the colours available in the current colormap. The helper function then scans the image columns, two rows at a time, generating the <i>Style</i> string for the character that will display a pair of vertically-adjacent pixels. We parallelized the scan over the image columns using the Rust crate <i>rayon</i> (Matsakis and Stone, 2014) to create a parallel iterator. Overall, Rust-based image rendering was 11% faster (146±13 ms/image) than our fastest Python implementation.</p><p>We designed the CLImax user interface with <i>textual</i> (McGugan, 2021) (Fig. 1A, bottom). <i>textual</i> is a Python package for the development of user interfaces and applications for the terminal. <i>textual</i> provides different widgets (<i>e.g.</i> buttons, dropdown boxes, text labels, etc.). We created a new <i>ImagePanel</i> widget that displays an image using the character-based renderer described above. <i>textual</i> apps provide a command palette that includes options to change the theme used to display the application, save a screenshot, or show a help panel. In addition, CLImax provides options to open a new image, zoom in or out, display the image with bilinear interpolation (particularly useful when zooming in/out), or save the current display.</p><p>CLImax can be invoked from the command line with different options. Similar to the JuNkIE API, the CLImax command line parameters enable image selection and substring and colour map specification, as well as initial zoom level, particularly important given that image rendering in the terminal is computationally intensive, with a cost that increases with the number of pixels to be rendered.</p><p>CLImax is also tested with <i>pytest</i>, using the <i>asyncio</i> plugin (Seifert, 2015) to test asynchronous user interaction. CLImax tests provide code coverage greater than 90%.</p>","references":[{"reference":"<p>Besson,S. <i>et al.</i> (2019) Bringing Open Data to Whole Slide Imaging. In, Reyes-Aldasoro,C.C. <i>et al.</i> (eds), <i>Digital Pathology</i>. Springer International Publishing, Cham, pp. 3–10.</p>","pubmedId":"","doi":""},{"reference":"<p>Burns,D. (2022) rich-pixels, https://github.com/darrenburns/rich-pixels.</p>","pubmedId":"","doi":""},{"reference":"<p>Casares-Arias,J. <i>et al.</i> (2021) Correlative confocal and scanning electron microscopy of cultured cells without using dedicated equipment. <i>STAR Protoc.</i>, <b>2</b>, 100727.</p>","pubmedId":"","doi":""},{"reference":"<p>von Chamier,L. <i>et al.</i> (2021) Democratising deep learning for microscopy with ZeroCostDL4Mic. <i>Nat Commun</i>, <b>12</b>, 2276.</p>","pubmedId":"","doi":""},{"reference":"<p>Cortes-Ortuno,D. <i>et al.</i> (2016) nbval, https://github.com/computationalmodelling/nbval.</p>","pubmedId":"","doi":""},{"reference":"<p>Crameri,F. (2023) Scientific colour maps, https://zenodo.org/records/8409685.</p>","pubmedId":"","doi":""},{"reference":"<p>Crameri,F. <i>et al.</i> (2020) The misuse of colour in science communication. <i>Nat. Commun.</i>, <b>11</b>, 5444.</p>","pubmedId":"","doi":""},{"reference":"<p>Granger,B.E. and Pérez,F. (2021) Jupyter: Thinking and Storytelling With Code and Data. <i>Comput. Sci. Eng.</i>, <b>23</b>, 7–14.</p>","pubmedId":"","doi":""},{"reference":"<p>Haase,R. (2021) stackview, https://github.com/haesleinhuepf/stackview.</p>","pubmedId":"","doi":""},{"reference":"<p>Harris,C.R. <i>et al.</i> (2020) Array programming with NumPy. <i>Nature</i>, <b>585</b>, 357–362.</p>","pubmedId":"","doi":""},{"reference":"<p>Hunter,J.D. (2007) Matplotlib: A 2D Graphics Environment. <i>Comput. Sci. Eng.</i>, <b>9</b>, 90–95.</p>","pubmedId":"","doi":""},{"reference":"<p>Jacquemet,G. (2021) Deep learning to analyse microscopy images. <i>The Biochemist</i>, <b>43</b>, 60–64.</p>","pubmedId":"","doi":""},{"reference":"<p>Kluyver,T. <i>et al.</i> (2016) Jupyter Notebooks – a publishing format for reproducible computational workflows.</p>","pubmedId":"","doi":""},{"reference":"<p>Krekel,H. <i>et al.</i> (2004) pytest, https://github.com/pytest-dev/pytest.</p>","pubmedId":"","doi":""},{"reference":"<p>Matsakis,N.D. and Klock II,F.S. (2014) The rust language. In, <i>ACM SIGAda Ada Letters</i>. ACM, pp. 103–104.</p>","pubmedId":"","doi":""},{"reference":"<p>Matsakis,N.D. and Stone,J. (2014) Rayon: A data parallelism library for Rust, https://github.com/rayon-rs/rayon/.</p>","pubmedId":"","doi":""},{"reference":"<p>McGugan,W. (2019) rich, https://github.com/Textualize/rich.</p>","pubmedId":"","doi":""},{"reference":"<p>McGugan,W. (2021) Textual, https://textual.textualize.io/.</p>","pubmedId":"","doi":""},{"reference":"<p>Meijering,E. and Cappellen,G. van (2007) Quantitative Biological Image Analysis. In, Shorte,S.L. and Frischknecht,F. (eds), <i>Imaging Cellular and Molecular Biological Functions</i>. Springer, Berlin, Heidelberg, pp. 45–70.</p>","pubmedId":"","doi":""},{"reference":"<p>Miles,A. (2015) zarr, https://github.com/zarr-developers/zarr-python.</p>","pubmedId":"","doi":""},{"reference":"<p>Morgado,L. <i>et al.</i> (2024) The rise of data-driven microscopy powered by machine learning. <i>J. Microsc.</i>, <b>295</b>, 85–92.</p>","pubmedId":"","doi":""},{"reference":"<p>Pichler,B.J. <i>et al.</i> (2008) Multimodal Imaging Approaches: PET/CT and PET/MRI. In, Semmler,W. and Schwaiger,M. (eds), <i>Molecular Imaging I</i>. Springer, Berlin, Heidelberg, pp. 109–132.</p>","pubmedId":"","doi":""},{"reference":"<p>Pimentel,J.F. <i>et al.</i> (2019) A Large-Scale Study About Quality and Reproducibility of Jupyter Notebooks. In, <i>2019 IEEE/ACM 16th International Conference on Mining Software Repositories (MSR)</i>., pp. 507–517.</p>","pubmedId":"","doi":""},{"reference":"<p>Qiu,D.L. (2023) Jupyter AI, https://github.com/jupyterlab/jupyter-ai.</p>","pubmedId":"","doi":""},{"reference":"<p>Samuel,S. and Mietchen,D. (2024) Computational reproducibility of Jupyter notebooks from biomedical publications. <i>GigaScience</i>, <b>13</b>, giad113.</p>","pubmedId":"","doi":""},{"reference":"<p>Seifert,M. (2015) pytest-asyncio, https://github.com/pytest-dev/pytest-asyncio.</p>","pubmedId":"","doi":""},{"reference":"<p>Senft,R.A. <i>et al.</i> (2023) A biologist’s guide to planning and performing quantitative bioimaging experiments. <i>PLOS Biol.</i>, <b>21</b>, e3002167.</p>","pubmedId":"","doi":""},{"reference":"<p>Sofroniew,N. <i>et al.</i> (2025) napari: a multi-dimensional image viewer for Python, https://zenodo.org/doi/10.5281/zenodo.3555620.</p>","pubmedId":"","doi":""},{"reference":"<p>Xiang,W. <i>et al.</i> (2018) Correlative live and super-resolution imaging reveals the dynamic structure of replication domains. <i>J. Cell Biol.</i>, <b>217</b>, 1973–1984.</p>","pubmedId":"","doi":""}],"title":"<p>JuNkIE-CLImax: exploring multidimensional images in notebooks and the terminal</p>","reviews":[],"curatorReviews":[]},{"id":"d5ff14c3-e283-432b-8050-023fcd176baf","decision":"publish","abstract":"<p>Modern microscopy generates multidimensional images. Graphical user interfaces allow visualization of multidimensional images, but image exploration is significantly harder in text-based environments. These include Jupyter notebooks, popular for the distribution of data analysis pipelines; and the terminal, often the only user interface available when accessing images in remote servers. We developed JuNkIE-CLImax, a pair of multidimensional image explorers designed to work in Jupyter notebooks and the terminal, respectively. JuNkIE-CLImax are written in Python, using Rust extensions to optimize performance; they are platform agnostic; and they provide application programming interfaces that enable integration into complex image visualization and analysis pipelines.</p>","acknowledgements":"<p>We are grateful to Negar Balaghi, Alexandra Korolov and Willow Peterson for comments on the manuscript. </p>","authors":[{"affiliations":["University of Toronto, Toronto, ON, CA","University of Toronto, Toronto, ON, CA","University of Toronto, Toronto, ON, CA","Hospital for Sick Children, Toronto, ON, CA"],"departments":["Institute of Biomedical Engineering","Ted Rogers Centre for Heart Research, Translational Biology and Engineering Program","Department of Cell and Systems Biology","Developmental and Stem Cell Biology Program"],"credit":["conceptualization","fundingAcquisition","methodology","project","resources","software","supervision","validation","visualization","writing_originalDraft","writing_reviewEditing","investigation"],"email":"rodrigo.fernandez.gonzalez@utoronto.ca","firstName":"Rodrigo","lastName":"Fernandez-Gonzalez","submittingAuthor":true,"correspondingAuthor":true,"equalContribution":false,"WBId":null,"orcid":"0000-0003-0770-744X"},{"affiliations":["University of Toronto, Toronto, ON, CA","University of Toronto, Toronto, ON, CA"],"departments":["Institute of Biomedical Engineering","Ted Rogers Centre for Heart Research, Translational Biology and Engineering Program"],"credit":["software","writing_reviewEditing"],"email":"raymond.hawkins@mail.utoronto.ca","firstName":"Raymond","lastName":"Hawkins","submittingAuthor":false,"correspondingAuthor":false,"equalContribution":false,"WBId":null,"orcid":null}],"awards":[],"conflictsOfInterest":"<p>The authors declare that there are no conflicts of interest present.</p>","dataTable":{"url":null},"extendedData":[],"funding":"<p>This work was supported by the Natural Sciences and Engineering Research Council of Canada (418438-13), the Canadian Institutes of Health Research (186188), the Canada Foundation for Innovation (30279), the Translational Biology and Engineering Program of the Ted Rogers Centre for Heart Research., and the University of Toronto EMHSeed Program. RFG is the Canada Research Chair in Quantitative Cell Biology and Morphogenesis.</p>","image":{"url":"https://portal.micropublication.org/uploads/e51ebf218e7555933af8a13dcfbec3be.png"},"imageCaption":"<p><b>(A)</b> JuNkIE (top) and CLImax (bottom) user interfaces displaying multidimensional images in a notebook and the terminal, respectively. JuNkIE-CLImax provide widgets to browse different image dimensions; expose multiple colormaps, including scientific colormaps; and conduct simple image operations, including rotation, flipping, zooming, reslicing and contrast adjustment. <b>(B)</b> Character-based image rendering. Sample image (left) and corresponding <i>rich</i> Style strings to render the image in the terminal (right), using a half-block character to display each pair of vertically-adjacent pixels. For instance, the Style parsed from \"<i>rgb(255,0,0) on rgb(0,255,255)</i>\", when associated with the half-block character, renders a red half-block on a cyan background, representing a cyan pixel in the top row and a red pixel in the bottom row, respectively<i>. </i>End-of-line characters (\"\\n\") indicate the ends of pairs of rows.</p>","imageTitle":"<p><b>JuNkIE-CLImax: multidimensional image explorers for notebooks and the terminal</b></p>","methods":"<p></p>","reagents":"<p></p>","patternDescription":"<p>Quantitative image analysis of microscopy datasets is a central tool in modern cell and developmental biology (Meijering and Cappellen, 2007; Senft et al., 2023). The advent of machine learning methods has established Python as the <i>de facto</i> standard for the analysis of biomedical images (Jacquemet, 2021; Morgado et al., 2024). Jupyter notebooks (Granger and Pérez, 2021) provide a beginner-friendly environment that enables prototyping and distribution&nbsp;of complex image processing pipelines (von Chamier et al., 2021). Platforms such as Google Colab or DigitalOcean provide free access to high-end computing capacity to execute notebooks, thus \"democratizing\" the use of resources that would otherwise be too costly. Notebooks facilitate data exploration and increase the reproducibility of data processing pipelines (Kluyver et al., 2016; Pimentel et al., 2019; Samuel and Mietchen, 2024). The leading position of notebooks for data analysis is cemented by the recent availability of large language models within notebooks (Qiu, 2023), which further facilitates development, debugging and execution of image processing and quantification routines. Thus, notebooks are a central element in the analysis of biomedical image data.</p><p>Both biological and medical imaging generate multidimensional data. Confocal and light sheet microscopies, for instance, allow collection of three-dimensional stacks (X, Y, Z) of different fluorescent reporters (wavelength), over the duration of a biological process (time). Multimodality imaging, such as correlative confocal and electron microscopies (Casares-Arias et al., 2021), confocal and super-resolution (Xiang et al., 2018), or the combination of anatomical and functional data in medical imaging (Pichler et al., 2008), introduces a sixth imaging dimension. Processing and analysis of multidimensional image datasets often requires image exploration at many stages in which rapid visualization and browsing are key steps. Two-dimensional images can be easily displayed in notebooks, <i>e.g.</i> with <i>matplotlib</i> (Hunter, 2007). However, few tools exist to display, browse and interact with multidimensional images in a notebook (Haase, 2021), and some of the available options provide complex user interfaces and functionality that prevent light-weight, inline multidimensional image browsing (Sofroniew et al., 2025).</p><p>Microscopy images are generally archived in remote backup servers. The advent of cloud-based storage services has only increased this trend.&nbsp;Remote and cloud-based servers often do not provide a graphical user interface, but simply a terminal-based, command line interface. Terminals can display text-based information about the images (file name, size, date, etc.), but do not allow image visualization. The lack of tools for image display on the terminal makes it hard to select images either for further processing or to generate figures for publication.</p><p>Here we introduce JuNkIE-CLImax, a pair of open source tools (https://bitbucket.org/rfg_lab/junkie and https://bitbucket.org/rfg_lab/climax) for the display and interactive visualization of multidimensional microscopy images in environments traditionally considered to be document or text-based. JuNkIE is a JUpyter NotebooK Image Explorer that enables the opening, display and simple manipulation of multidimensional images in Jupyter notebooks. CLImax, a Command Line IMAge eXplorer, allows users to open, visualize and browse multidimensional images on the terminal, using character-based strategies for image rendering.</p><p></p><p>JuNkIE-CLImax: multidimensional image explorers</p><p>JuNkIE-CLImax can load multidimensional images in the multi-page TIFF format often found in microscopy (Besson et al., 2019), as well as images stored in the increasingly popular <i>zarr</i> array format (Miles, 2015). JuNkIE-CLImax can also import file sequences that represent different dimensions (<i>e.g.</i> time or wavelength) of a multidimensional image. Internally, images are stored using <i>numpy</i>, a package for numerical computation, and its <i>ndarray</i> data structure to represent multidimensional arrays (Harris et al., 2020). JuNkIE-CLImax display a two-dimensional view of a multidimensional image (Fig. 1A). Both packages provide sliders to select a specific Z-plane, time point and channel from the multidimensional image stored in memory, using both mouse and keyboard-based interactions. JuNkIE-CLImax continuously update the displayed image in real time in response to user input. To enable use in settings with reduced compute power (<i>e.g.</i> remote storage servers), it is possible to disable the continuous update of the display, such that updates only occur when the user interaction is completed (<i>e.g.</i> when the mouse button is released, but not while the mouse is dragged). XY, XZ or YZ sectioning planes can be selected. Additionally, JuNkIE-CLImax provide functionality for simple image manipulation. This includes rotation and flipping (both horizontal and vertical), colormap selection and inversion (including all the colormaps available in <i>matplotlib</i> (Crameri et al., 2020; Crameri, 2023)), and both manual and automated contrast adjustment.</p><p></p><p><b><i>JuNkIE</i></b></p><p>JuNkIE displays images using the <i>Figure</i> class in <i>matplotlib</i>. A <i>matplotlib</i> <i>Figure</i> can hold different plot elements, including images. The <i>matplotlib</i> <i>Figure</i> provides a toolbar with options to pan, zoom in and out, reset the view, or save a snapshot (Fig. 1A, top).</p><p>JuNkIE provides a simple application programming interface (API). Using the JuNkIE API it is possible to open images from disk, by providing a file or folder path, or to view volumetric information already loaded as an <i>ndarray</i>. Substrings can be used to distinguish which files in an image sequence store specific dimensions (<i>e.g.</i> different image channels). Lastly, the colormap used to initially display an image, as well as the size of the figure can be determined with input parameters when invoking JuNkIE.&nbsp;&nbsp;&nbsp;&nbsp;</p><p>JuNkIE is distributed with a test suite using <i>pytest</i> (Krekel et al., 2004) and the <i>nbval</i> plugin for notebook-based testing (Cortes-Ortuno et al., 2016), with code coverage over 90%.</p><p></p><p><b><i>CLImax</i></b></p><p>To display images on the terminal, we created a character-based image renderer. The image renderer uses <i>rich</i>, a Python package for text formatting that allows the use of coloured characters in the terminal (McGugan, 2019; Burns, 2022). Our image renderer takes a two-dimensional <i>ndarray</i> as its input, and produces a sequence of <i>rich</i> Segments, each consisting of a character and some formatting (a <i>Style</i>), punctuated by end-of-line characters at the end of each image row (Fig. 1B). <i>rich Styles</i> determine the colours used to display a character and its background. Colours are defined by the corresponding red, green and blue (rgb) components, specified as a string. Initially, we rendered each pixel using a space character (' '), assigning the pixel value as the background colour and no foreground colour. Because characters on the terminal are rectangular (elongated along the vertical axis), we rendered each image column twice to obtain square pixels. As a consequence, image rendering was relatively slow, requiring 380±23 ms (mean±standard deviation) to render a 512x672 pixel image on an Apple M3 Max equipped with 48 GB of RAM.</p><p>To optimize image rendering, we first reduced the number of terminal characters necessary to display a pixel. We took advantage of the half-block character ('▄') to visualize pairs of vertically-adjacent pixels (same column, consecutive rows) with a single terminal character (Fig. 1B). For each pair of pixels, we rendered the bottom pixel by assigning its value as the foreground colour of a half-block character, and the top pixel by assigning its value as the background colour of the same half-block character (Fig. 1B). This approach allowed us to display each pixel with half a character, in contrast to the previous method, which required two characters per pixel. We further accelerated rendering by creating a <i>Style</i> cache that used a Python dictionary to store the <i>rich</i> <i>Styles</i> corresponding to parsed colour-strings. After these optimizations, rendering speed increased by 57% (163±13 ms/image) and memory consumption decreased by a factor of four.</p><p>To further speed up image display, we implemented the hot-loop of the renderer in Rust (Matsakis and Klock II, 2014). The Rust code implements a helper function with two inputs, a two-dimensional image, and a colour lookup table that contains the string representation of each of the colours available in the current colormap. The helper function then scans the image columns, two rows at a time, generating the <i>Style</i> string for the character that will display a pair of vertically-adjacent pixels. We parallelized the scan over the image columns using the Rust crate <i>rayon</i> (Matsakis and Stone, 2014) to create a parallel iterator. Overall, Rust-based image rendering was 11% faster (146±13 ms/image) than our fastest Python implementation.</p><p>We designed the CLImax user interface with <i>textual</i> (McGugan, 2021) (Fig. 1A, bottom). <i>textual</i> is a Python package for the development of user interfaces and applications for the terminal. <i>textual</i> provides different widgets (<i>e.g.</i> buttons, dropdown boxes, text labels, etc.). We created a new <i>ImagePanel</i> widget that displays an image using the character-based renderer described above. <i>textual</i> apps provide a command palette that includes options to change the theme used to display the application, save a screenshot, or show a help panel. In addition, CLImax provides options to open a new image, zoom in or out, display the image with bilinear interpolation (particularly useful when zooming in/out), or save the current display.</p><p>CLImax can be invoked from the command line with different options. Similar to the JuNkIE API, the CLImax command line parameters enable image selection and substring and colour map specification, as well as initial zoom level, particularly important given that image rendering in the terminal is computationally intensive, with a cost that increases with the number of pixels to be rendered.</p><p>CLImax is also tested with <i>pytest</i>, using the <i>asyncio</i> plugin (Seifert, 2015) to test asynchronous user interaction. CLImax tests provide code coverage greater than 90%.</p>","references":[{"reference":"<p>Besson Sb, Leigh R, Linkert M, Allan C, Burel JM, Carroll M, et al., Swedlow. 2019. Bringing Open Data to Whole Slide Imaging. Lecture Notes in Computer Science,Digital Pathology : 3-10.</p>","pubmedId":"","doi":"10.1007/978-3-030-23937-4_1"},{"reference":"<p>Burns,D. (2022) rich-pixels, https://github.com/darrenburns/rich-pixels.</p>","pubmedId":"","doi":""},{"reference":"<p>Casares-Arias J, Alonso MA, San Paulo l, González MaU. 2021. Correlative confocal and scanning electron microscopy of cultured cells without using dedicated equipment. STAR Protocols 2: 100727.</p>","pubmedId":"","doi":"10.1016/j.xpro.2021.100727"},{"reference":"<p>von Chamier L, Laine RF, Jukkala J, Spahn C, Krentzel D, Nehme E, et al., Henriques. 2021. Democratising deep learning for microscopy with ZeroCostDL4Mic. Nature Communications 12: 10.1038/s41467-021-22518-0.</p>","pubmedId":"","doi":"10.1038/s41467-021-22518-0"},{"reference":"<p>Cortes-Ortuno,D. <i>et al.</i> (2016) nbval, https://github.com/computationalmodelling/nbval.</p>","pubmedId":"","doi":""},{"reference":"<p>Crameri,F. (2023) Scientific colour maps, https://zenodo.org/records/8409685.</p>","pubmedId":"","doi":"10.5281/zenodo.8409685"},{"reference":"<p>Crameri F, Shephard GE, Heron PJ. 2020. The misuse of colour in science communication. Nature Communications 11: 10.1038/s41467-020-19160-7.</p>","pubmedId":"","doi":"10.1038/s41467-020-19160-7"},{"reference":"<p>Granger BE, Perez F. 2021. Jupyter: Thinking and Storytelling With Code and Data. Computing in Science &amp; Engineering 23: 7-14.</p>","pubmedId":"","doi":"10.1109/MCSE.2021.3059263"},{"reference":"<p>Haase,R. (2021) stackview, https://github.com/haesleinhuepf/stackview.</p>","pubmedId":"","doi":""},{"reference":"<p>Harris CR, Millman KJ, van der Walt SfJ, Gommers R, Virtanen P, Cournapeau D, et al., Oliphant. 2020. Array programming with NumPy. Nature 585: 357-362.</p>","pubmedId":"","doi":"10.1038/s41586-020-2649-2"},{"reference":"<p>Hunter JD. 2007. Matplotlib: A 2D Graphics Environment. Computing in Science &amp; Engineering 9: 90-95.</p>","pubmedId":"","doi":"10.1109/MCSE.2007.55"},{"reference":"<p>Jacquemet G. 2021. Deep learning to analyse microscopy images. The Biochemist 43: 60-64.</p>","pubmedId":"","doi":"10.1042/bio_2021_167"},{"reference":"<p>Kluyver Thomas , Ragan-Kelley Benjamin , Pérez Fernando , Granger Brian , Bussonnier Matthias , Frederic Jonathan , et al., Jupyter Development Team. 2016. Jupyter Notebooks - a publishing format for reproducible computational workflows. Positioning and Power in Academic Publishing: Players, Agents and Agendas : 10.3233/978-1-61499-649-1-87.</p>","pubmedId":"","doi":"10.3233/978-1-61499-649-1-87"},{"reference":"<p>Krekel,H. <i>et al.</i> (2004) pytest, https://github.com/pytest-dev/pytest.</p>","pubmedId":"","doi":""},{"reference":"<p>Matsakis,N.D. and Klock II,F.S. (2014) The rust language. In, <i>ACM SIGAda Ada Letters</i>. ACM, pp. 103–104.</p>","pubmedId":"","doi":""},{"reference":"<p>Matsakis,N.D. and Stone,J. (2014) Rayon: A data parallelism library for Rust, https://github.com/rayon-rs/rayon/.</p>","pubmedId":"","doi":""},{"reference":"<p>McGugan,W. (2019) rich, https://github.com/Textualize/rich.</p>","pubmedId":"","doi":""},{"reference":"<p>McGugan,W. (2021) Textual, https://textual.textualize.io/.</p>","pubmedId":"","doi":""},{"reference":"<p>Meijering E, Cappellen Gv. 2007. Quantitative Biological Image Analysis. Principles and Practice,Imaging Cellular and Molecular Biological Functions : 45-70.</p>","pubmedId":"","doi":"10.1007/978-3-540-71331-9_2"},{"reference":"<p>Miles,A. (2015) zarr, https://github.com/zarr-developers/zarr-python.</p>","pubmedId":"","doi":""},{"reference":"<p>Morgado L, Gómez‐de‐Mariscal E, Heil HS, Henriques R. 2024. The rise of data‐driven microscopy powered by machine learning. Journal of Microscopy 295: 85-92.</p>","pubmedId":"","doi":"10.1111/jmi.13282"},{"reference":"<p>Pichler BJ, Judenhofer MS, Pfannenberg C. 2008. Multimodal Imaging Approaches: PET/CT and PET/MRI. Handbook of Experimental Pharmacology,Molecular Imaging I : 109-132.</p>","pubmedId":"","doi":"10.1007/978-3-540-72718-7_6"},{"reference":"<p>Pimentel JF, Murta L, Braganholo V, Freire J. 2019. A Large-Scale Study About Quality and Reproducibility of Jupyter Notebooks. 2019 IEEE/ACM 16th International Conference on Mining Software Repositories (MSR) : 507-517.</p>","pubmedId":"","doi":"10.1109/MSR.2019.00077"},{"reference":"<p>Qiu,D.L. (2023) Jupyter AI, https://github.com/jupyterlab/jupyter-ai.</p>","pubmedId":"","doi":""},{"reference":"<p>Samuel S, Mietchen D. 2024. Computational reproducibility of Jupyter notebooks from biomedical publications. GigaScience 13: 10.1093/gigascience/giad113.</p>","pubmedId":"","doi":"10.1093/gigascience/giad113"},{"reference":"<p>Seifert,M. (2015) pytest-asyncio, https://github.com/pytest-dev/pytest-asyncio.</p>","pubmedId":"","doi":""},{"reference":"<p>Senft RA, Diaz-Rohrer B, Colarusso P, Swift L, Jamali N, Jambor H, et al., Cimini. 2023. A biologist’s guide to planning and performing quantitative bioimaging experiments. PLOS Biology 21: e3002167.</p>","pubmedId":"","doi":"10.1371/journal.pbio.3002167"},{"reference":"<p>Sofroniew,N. <i>et al.</i> (2025) napari: a multi-dimensional image viewer for Python, https://zenodo.org/doi/10.5281/zenodo.3555620.</p>","pubmedId":"","doi":"10.5281/zenodo.3555620"},{"reference":"<p>Xiang W, Roberti MJ, Hériché JK, Huet Sb, Alexander S, Ellenberg J. 2018. Correlative live and super-resolution imaging reveals the dynamic structure of replication domains. Journal of Cell Biology 217: 1973-1984.</p>","pubmedId":"","doi":"10.1083/jcb.201709074"}],"title":"<p>JuNkIE-CLImax: exploring multidimensional images in notebooks and the terminal</p>","reviews":[],"curatorReviews":[]}]}},"species":{"species":[{"value":"acer saccharum","label":"Acer saccharum","imageSrc":"","imageAlt":"","mod":"TreeGenes","modLink":"https://treegenesdb.org","linkVariable":""},{"value":"achillea millefolium","label":"Achillea millefolium","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"acinetobacter baylyi","label":"Acinetobacter baylyi","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"actinobacteria bacterium","label":"Actinobacteria bacterium","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"adelges tsugae","label":"Adelges tsugae","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"adenocaulon chilense","label":"Adenocaulon chilense","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"aedes japonicus","label":"Aedes japonicus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"aegorhinus vitulus","label":"Aegorhinus vitulus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"alaimidae","label":"Alaimidae","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"allobates femoralis","label":"Allobates femoralis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"alnus glutinosa","label":"Alnus glutinosa","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"alosa aestivalis","label":"Alosa aestivalis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"alosa pseudoharengus","label":"Alosa pseudoharengus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"alternaria alternata","label":"Alternaria alternata","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"amynthas agrestis","label":"Amynthas Agrestis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"ancylostoma caninum","label":"Ancylostoma caninum","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"ancylostoma ceylanicum","label":"Ancylostoma ceylanicum","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"anemone multifida","label":"Anemone multifida","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"anguilla rostrata","label":"Anguilla rostrata","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"anisakis simplex","label":"Anisakis simplex","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"anomala albopilosa","label":"Anomala albopilosa","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"anthomyiidae sp","label":"Anthomyiidae sp","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"anthomyiidae sp","label":"Anthomyiidae sp","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"arabidopsis","label":"Arabidopsis","imageSrc":"arabidopsis.png","imageAlt":"Arabidopsis graphic by Zoe Zorn CC BY 4.0","mod":"TAIR","modLink":"https://arabidopsis.org","linkVariable":""},{"value":"architeuthis dux","label":"Architeuthis dux","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"arion vulgaris","label":"Arion vulgaris","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"armeria","label":"Armeria","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"artemia","label":"Artemia","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"arthrobacter sp.","label":"Arthrobacter sp.","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"ascaridia","label":"Ascaridia","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"ascaridia galli","label":"Ascaridia galli","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"asparagopsis taxiformis","label":"Asparagopsis taxiformis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"astatotilapia burtoni","label":"Astatotilapia burtoni","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"avena sativa","label":"Avena sativa","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"aves","label":"Aves","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"bacillus","label":"Bacillus (firmicutes)","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"bacillus cereus","label":"Bacillus cereus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"bacillus mycoides","label":"Bacillus mycoides","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"bacillus subtilis","label":"Bacillus subtilis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"bacillus thuringiensis","label":"Bacillus thuringiensis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"bacillus toyonensis","label":"Bacillus toyonensis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"bacillus wiedmannii","label":"Bacillus wiedmannii","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"bacteria","label":"Bacteria","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"bacteriophage","label":"Bacteriophage","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"bactrocera","label":"Bactrocera sp.","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"batrachospermum gelatinosum","label":"Batrachospermum gelatinosum","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"betula lenta","label":"Betula lenta","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"betula nigra","label":"Betula nigra","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"bombus dahlbohmii","label":"Bombus dahlbohmii","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"bombus terrestris","label":"Bombus terrestris","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"bombyx mori","label":"Bombyx mori","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"bos taurus","label":"Bos Taurus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"brachygobius doriae","label":"Brachygobius doriae","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"brassica oleracea","label":"Brassica oleracea","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"brassica rapa","label":"Brassica rapa","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"brugia malayi","label":"Brugia malayi","imageSrc":"","imageAlt":"","mod":"WormBase","modLink":"www.wormbase.org","linkVariable":""},{"value":"burkholderia thailandensis","label":"Burkholderia thailandensis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"buttiauxella","label":"Buttiauxella","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"caenorhabditis brenneri","label":"Caenorhabditis brenneri","imageSrc":"","imageAlt":"","mod":"WormBase","modLink":"www.wormbase.org","linkVariable":""},{"value":"caenorhabditis briggsae","label":"Caenorhabditis briggsae","imageSrc":"","imageAlt":"","mod":"WormBase","modLink":"www.wormbase.org","linkVariable":""},{"value":"c. elegans","label":"Caenorhabditis elegans","imageSrc":"c-elegans.jpg","imageAlt":"C. elegans graphic by Zoe Zorn CC BY 4.0","mod":"WormBase","modLink":"https://wormbase.org","linkVariable":""},{"value":"caenorhabditis inopinata","label":"Caenorhabditis inopinata","imageSrc":"","imageAlt":"","mod":"WormBase","modLink":"www.wormbase.org","linkVariable":""},{"value":"caenorhabditis japonica","label":"Caenorhabditis japonica","imageSrc":"","imageAlt":"","mod":"WormBase","modLink":"www.wormbase.org","linkVariable":""},{"value":"caenorhabditis nigoni","label":"Caenorhabditis nigoni","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"caenorhabditis remanei","label":"Caenorhabditis remanei","imageSrc":"","imageAlt":"","mod":"WormBase","modLink":"www.wormbase.org","linkVariable":""},{"value":"caenorhabditis tropicalis","label":"Caenorhabditis tropicalis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"calidifontibacillus","label":"Calidifontibacillus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"calidifontibacillus erzuremensis","label":"Calidifontibacillus erzuremensis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"calliphora sp","label":"Calliphora sp","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"caltha sagittata","label":"Caltha sagittata","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"cambarus latimanus","label":"Cambarus latimanus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"candida albicans","label":"Candida albicans","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"canis familiaris","label":"Canis familiaris","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"cannabis sativa","label":"Cannabis sativa","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"caretta caretta","label":"Caretta caretta","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"cassiopea xamachana","label":"Cassiopea xamachana","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"caulobacter vibrioides","label":"Caulobacter vibrioides","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"cephalopods","label":"Cephalopoda","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"cerastium arvense","label":"Cerastium arvense","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"ceriodaphnia","label":"Ceriodaphnia","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"ceroglossus suturalis","label":"Ceroglossus suturalis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"chaetoceros","label":"Chaetoceros","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"chamaecrista fasciculata","label":"Chamaecrista fasciculata","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"chilicola chalcidiformis","label":"Chilicola chalcidiformis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"chitinimonas","label":"Chitinimonas","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"chlamydomonas reinhardtii","label":"Chlamydomonas reinhardtii","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"chromobacterium","label":"Chromobacterium","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"chrysemys picta","label":"Chrysemys picta","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"chrysoperla rufilabris","label":"Chrysoperla rufilabris","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"citrus","label":"Citrus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"clavibacter sp.","label":"Clavibacter sp.","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"colinus virginianus","label":"Colinus virginianus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"crassostrea virginica","label":"Crassostrea virginica","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"crithidia fasciculata","label":"Crithidia fasciculata","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"cutibacterium acnes","label":"Cutibacterium acnes","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"cyanobacteria","label":"Cyanobacteria","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"daphnia","label":"Daphnia","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"daphnia pulex","label":"Daphnia pulex","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"diabrotica virgifera","label":"Diabrotica virgifera","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"diabrotica virgifera virgifera virus 1","label":"Diabrotica virgifera virgifera virus 1","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"d. discoideum","label":"Dictyostelium discoideum","imageSrc":"dicty.png","imageAlt":"D. discoideum","mod":"dictyBase","modLink":"http://dictybase.org","linkVariable":""},{"value":"diptera","label":"Diptera","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"dotocryptus bellicosus","label":"Dotocryptus bellicosus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"drechmeria coniospora","label":"Drechmeria coniospora","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"drosophila","label":"Drosophila","imageSrc":"drosophila.png","imageAlt":"Drosophila graphic by Zoe Zorn CC BY 4.0","mod":"FlyBase","modLink":"https://flybase.org/doi/","linkVariable":"doi"},{"value":"dryopteris campyloptera","label":"Dryopteris campyloptera","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"dryopteris expansa","label":"Dryopteris expansa","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"dryopteris intermedia","label":"Dryopteris intermedia","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"dugesia dorotocephala","label":"Dugesia dorotocephala","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"elasmobranchii","label":"Elasmobranchii","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"embryophyta","label":"Embryophyta","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"enoploteuthis chunii","label":"Enoploteuthis chunii","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"enterobacter aerogenes","label":"Enterobacter aerogenes","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"enterococcus raffinosus","label":"Enterococcus raffinosus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"epichloë coenophiala","label":"Epichloë coenophiala","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"equus caballus","label":"Equus caballus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"erigeron sp","label":"Erigeron sp","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"eristalis","label":"Eristalis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"eruca vesicaria","label":"Eruca vesicaria","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"erwinia carotovora","label":"Erwinia carotovora","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"erythronium americanum","label":"Erythronium americanum","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"escherichia coli","label":"Escherichia coli","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"eukaryota","label":"Eukaryotes","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"felis catus","label":"Felis catus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"francisella novicida","label":"Francisella novicida","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"francisella tularensis","label":"Francisella tularensis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"fraxinus americana","label":"Fraxinus americana","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"fucus distichus","label":"Fucus distichus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"fungi","label":"Fungi","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"gasteropelecus sp.","label":"Gasteropelecus sp.","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"geranium sp","label":"Geranium sp","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"girardia","label":"Girardia","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"glaucomys volans","label":"Glaucomys volans","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"glycine max","label":"Glycine max","imageSrc":"","imageAlt":"","mod":"Soybase","modLink":"https://soybase.org","linkVariable":""},{"value":"glyptemys insculpta","label":"Glyptemys insculpta","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"gossypium hirsutum","label":"Gossypium hirsutum","imageSrc":"","imageAlt":"","mod":"CottonGen","modLink":"https://www.cottongen.org/","linkVariable":""},{"value":"gromphadorhina portentosa","label":"Gromphadorhina portentosa","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"gryllodes sigillatus","label":"Gryllodes sigillatus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"haliotis rufescens","label":"Haliotis rufescens","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"hepacivirus hominis","label":"Hepatitis C Virus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"herpes simplex virus type 1","label":"Herpes simplex virus type 1","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"human","label":"Human","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"human coronavirus oc43","label":"Human coronavirus OC43","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"hydra vulgaris","label":"Hydra vulgaris","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"hydropsyche sp","label":"Hydropsyche sp","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"hymenoptera","label":"Hymenoptera","imageSrc":"","imageAlt":"","mod":"Hymenoptera Genome Database","modLink":"https://hymenoptera.elsiklab.missouri.edu/","linkVariable":""},{"value":"hypochaeris radicata","label":"Hypochaeris radicata","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"hypodynerus vespiformis","label":"Hypodynerus vespiformis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"iflaviridae","label":"Iflaviridae","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"iflavuris","label":"Iflavirus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"ipomoea hederacea","label":"Ipomoea hederacea","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"ischnomera","label":"Ischnomera","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"ischnomera ruficollis","label":"Ischnomera ruficollis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"julidochromis marlieri","label":"Julidochromis marlieri","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"juniperus virginiana","label":"Juniperus virginiana","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"kluyveromyces marxianus","label":"Kluyveromyces marxianus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"l. casei","label":"L. casei","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"lacticaseibacillus casei","label":"Lacticaseibacillus casei","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"larentiinae sp","label":"Larentiinae sp","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"laurus nobilis","label":"Laurus nobilis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"lepidoptera","label":"Lepidoptera","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"leucanthemum vulgare","label":"Leucanthemum vulgare","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"linepithema humile","label":"Linepithema humile","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"liometopum occidentale","label":"Liometopum occidentale","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"lolium arundinaceum","label":"Lolium arundinaceum","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"lumbriculus variegatus","label":"Lumbriculus variegatus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"lumbricus terrestris","label":"Lumbricus terrestris","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"lupinus polyphyllus","label":"Lupinus polyphyllus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"lycorma delicatula","label":"Lycorma delicatula","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"lynx rufus","label":"Lynx rufus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"magnaporthe oryzae","label":"Magnaporthe oryzae","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"mammalia","label":"Mammalia","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"manihot esculenta","label":"Manihot esculenta","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"medicago lupulina","label":"Medicago lupulina","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"meloidogyne","label":"Meloidogyne","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"mimus polyglottos","label":"Mimus polyglottos","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"bryophyta","label":"Mosses","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"mouse","label":"Mouse","imageSrc":"","imageAlt":"","mod":"MGI","modLink":"https://informatics.jax.org","linkVariable":""},{"value":"m. minutoides","label":"Mus minutoides","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"mycobacterium smegmatis","label":"Mycobacterium smegmatis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"nakaseomyces glabratus","label":"Nakaseomyces glabratus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"nauphoeta cinerea","label":"Nauphoeta cinerea","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"neurospora","label":"Neurospora","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"n. benthamiana","label":"Nicotiana benthamiana","imageSrc":"","imageAlt":"","mod":"Solgenomics Network","modLink":"https://solgenomics.net/organism/Nicotiana_benthamiana/genome","linkVariable":""},{"value":"nicotiana tabacum","label":"Nicotiana tabacum","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"noctuidae","label":"Noctuidae","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"noctuidae sp","label":"Noctuidae sp","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"nothobranchius furzeri","label":"Nothobranchius furzeri","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"onchocerca volvulus","label":"Onchocerca volvulus","imageSrc":"","imageAlt":"","mod":"WormBase","modLink":"www.wormbase.org","linkVariable":""},{"value":"orconectes virilis","label":"Orconectes virilis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"ormia ochracea","label":"Ormia ochracea","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"o. sativa","label":"Oryza sativa","imageSrc":"","imageAlt":"","mod":"Gramene","modLink":"https://www.gramene.org/","linkVariable":""},{"value":"other","label":"Other","imageSrc":"","imageAlt":"","mod":null,"modLink":null,"linkVariable":null},{"value":"oxalis enneaphylla","label":"Oxalis enneaphylla","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"paenarthrobacter nicotinovorans","label":"Paenarthrobacter nicotinovorans","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"paenarthrobacter nicotinovorans","label":"Paenarthrobacter nicotinovorans","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"pantoea","label":"Pantoea","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"pantoea agglomerans","label":"Pantoea agglomerans","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"papaver sp","label":"Papaver sp","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"paramecium bursaria","label":"Paramecium bursaria","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"partitiviridae","label":"Partitiviridae","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"pelodiscus sinensis","label":"Pelodiscus sinensis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"perezia recurvata","label":"Perezia recurvata","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"petromyzon marinus","label":"Petromyzon marinus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"photinus pyralis","label":"Photinus pyralis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"photinus pyralis associated partiti-like virus","label":"Photinus pyralis associated partiti-like virus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"photinus pyralis iflavirus 1","label":"Photinus pyralis iflavirus 1","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"physcomitrium patens","label":"Physcomitrium patens","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"pinus strobus","label":"Pinus strobus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"pinus taeda","label":"Pinus taeda","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"platycheirus","label":"Platycheirus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"plectus sambesii","label":"Plectus sambesii","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"pogonomyrmex occidentalis","label":"Pogonomyrmex occidentalis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"poncirus trifoliata","label":"Poncirus trifoliata","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"populus deltoides","label":"Populus deltoides","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"potato virus y","label":"Potato virus Y","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"primula magellanica","label":"Primula magellanica","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"pristionchus pacificus","label":"Pristionchus pacificus","imageSrc":"","imageAlt":"","mod":"WormBase","modLink":"www.wormbase.org","linkVariable":""},{"value":"prunus persica","label":"Prunus persica","imageSrc":"","imageAlt":"","mod":"Genome Database for Rosaceae","modLink":"https://www.rosaceae.org/","linkVariable":""},{"value":"psalmopoeus iriminia","label":"Psalmopoeus iriminia","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"pseudanabaena sp.","label":"Pseudanabaena sp.","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"pseudomonas","label":"Pseudomonas","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"pseudomonas aeruginosa","label":"Pseudomonas aeruginosa","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"pseudomonas glycinae","label":"Pseudomonas glycinae","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"pseudomonas putida","label":"Pseudomonas putida","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"pseudomonas syringae","label":"Pseudomonas syringae","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"pterophyllum scalare","label":"Pterophyllum scalare","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"python regius","label":"Python regius","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"quercus macrocarpa","label":"Quercus macrocarpa","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"ralstonia solanacearum","label":"Ralstonia solanacearum","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"ranitomeya imitator","label":"Ranitomeya imitator","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"ranunculus peduncularis","label":"Ranunculus peduncularis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"rat","label":"Rat","imageSrc":"","imageAlt":"","mod":"RGD","modLink":"https://rgd.mcw.edu","linkVariable":""},{"value":"rheinheimera","label":"Rheinheimera","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"ribes rubrum","label":"Ribes rubrum","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"sars-cov-2","label":"SARS-CoV-2","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"s. cerevisiae","label":"Saccharomyces cerevisiae","imageSrc":"yeast.png","imageAlt":"Yeast graphic by Zoe Zorn CC BY 4.0","mod":"SGD","modLink":"https://yeastgenome.org","linkVariable":""},{"value":"saccharomyces paradoxus","label":"Saccharomyces paradoxus ","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"s. uvarum","label":"Saccharomyces uvarum","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"schistosoma","label":"Schistosoma","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"schizosaccharomyces japonicus","label":"Schizosaccharomyces japonicus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"s. pombe","label":"Schizosaccharomyces pombe","imageSrc":"pombe.png","imageAlt":"Pombe graphic by Zoe Zorn © Caltech","mod":"PomBase","modLink":"https://www.pombase.org/reference/PMID:","linkVariable":"pmId"},{"value":"schmidtea mediterranea","label":"Schmidtea mediterranea","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"senecio sp","label":"Senecio sp","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"simocephalus","label":"Simocephalus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"siraitia grosvenorii","label":"Siraitia grosvenorii","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"solanum lycopersicum","label":"Solanum lycopersicum","imageSrc":"","imageAlt":"","mod":"Solgenomics Network","modLink":"https://solgenomics.net/organism/1/view/","linkVariable":""},{"value":"sorghum","label":"Sorghum","imageSrc":"","imageAlt":"","mod":"SorghumBase","modLink":"https://www.sorghumbase.org","linkVariable":""},{"value":"spiroplasma eriocheiris","label":"Spiroplasma eriocheiris","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"staphylococcus aureus","label":"Staphylococcus aureus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"staphylococcus epidermidis","label":"Staphylococcus epidermidis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"steinernema carpocapsae","label":"Steinernema carpocapsae","imageSrc":"","imageAlt":"","mod":"WormBase","modLink":"https://wormbase.org","linkVariable":""},{"value":"steinernema hermaphroditum","label":"Steinernema hermaphroditum","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"stenotrophomonas geniculata","label":"Stenotrophomonas geniculata","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"streptococcus gordonii ","label":"Streptococcus gordonii ","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"streptococcus mutans","label":"Streptococcus mutans","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":" streptococcus pneumoniae","label":"Streptococcus pneumoniae","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"s. purpuratus","label":"Strongylocentrotus purpuratus","imageSrc":"","imageAlt":"","mod":"Echinobase","modLink":"https://www.echinobase.org","linkVariable":""},{"value":"strongyloides ratti","label":"Strongyloides ratti","imageSrc":"","imageAlt":"","mod":"WormBase","modLink":"www.wormbase.org","linkVariable":""},{"value":"sulfolobus","label":"Sulfolobus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"symphoricarpos albus","label":"Symphoricarpos albus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"syncirsodes","label":"Syncirsodes","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"synechococcus elongatus","label":"Synechococcus elongatus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"syrphidae","label":"Syrphidae","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"tarantobelus jeffdanielsi","label":"Tarantobelus jeffdanielsi","imageSrc":"","imageAlt":"","mod":"WormBase","modLink":"www.wormbase.org","linkVariable":""},{"value":"taraxacum officinale","label":"Taraxacum officinale","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"tatochila theodice","label":"Tatochila theodice","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"tetrahymena","label":"Tetrahymena","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"tetramorium immigrans","label":"Tetramorium immigrans","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"tomato brown rugose fruit virus","label":"ToBRFV","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"trachemys scripta","label":"Trachemys scripta","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"tribolium castaneum","label":"Tribolium castaneum","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"trichoptera","label":"Trichoptera","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"trichuris muris","label":"Trichuris muris","imageSrc":"","imageAlt":"","mod":"WormBase","modLink":"www.wormbase.org","linkVariable":""},{"value":"trifolium repens","label":"Trifolium repens","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"trypoxylus dichotomus","label":"Trypoxylus dichotomus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"tsuga canadensis","label":"Tsuga canadensis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"ulva expansa","label":"Ulva expansa","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"universal","label":"Universal","imageSrc":"","imageAlt":"","mod":null,"modLink":null,"linkVariable":null},{"value":"vargula hilgendorfii","label":"Vargula hilgendorfii","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"vespula vulgaris","label":"Vespula vulgaris","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"virus","label":"Virus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"watasenia scintillans","label":"Watasenia scintillans","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"wolbachia pipientis","label":"Wolbachia pipientis","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"xenopus","label":"Xenopus","imageSrc":"xenopus.png","imageAlt":"Xenopus graphic by Zoe Zorn CC BY 4.0","mod":"XenBase","modLink":"https://xenbase.org","linkVariable":""},{"value":"xenorhabdus griffiniae","label":"Xenorhabdus griffiniae","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"yramea cytheris","label":"Yramea cytheris","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"zaprionus indianus","label":"Zaprionus indianus","imageSrc":"","imageAlt":"","mod":"","modLink":"","linkVariable":""},{"value":"zea mays","label":"Zea mays","imageSrc":"","imageAlt":"","mod":"MaizeDB","modLink":"","linkVariable":""},{"value":"zebrafish","label":"Zebrafish","imageSrc":"zebrafish.png","imageAlt":"Zebrafish graphic by Zoe Zorn CC BY 4.0","mod":"ZFIN","modLink":"https://zfin.org","linkVariable":""}]}},"pageContext":{"id":"f52eaf7d-d071-4cc4-927e-14ecd4e9a4eb","citedBy":[],"parsedCsv":{"csvHeader":[],"csvData":[]}}},
    "staticQueryHashes": ["2114697108"]}