NanoPlot: quality control plots for long read sequencing data
Plotting scripts for long read sequencing data
At a glance
- What is it?
- NanoPlot is a Python plotting suite for Oxford Nanopore long read data and alignments, turning fastq, bam, cram, summary and fasta inputs into read length and quality plots, a statistical summary and an HTML report. It is MIT licensed, installable with pip or conda, and also runs as a web service.
- Who is it for?
- NanoPlot fits a sequencing group that wants a repeatable read length and basecall quality picture per run, and it fits a pipeline that already produces basecaller output in any of the supported formats and wants plots rather than just numbers. It does not fit a team that needs alignment review, variant calling or a general purpose multi-omics report, since the scope is read level quality control.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 23 days ago.
- What is it written in?
- Mainly HTML, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What NanoPlot produces and what it does not
NanoPlot is a plotting tool for long read sequencing data and alignments, and the project description is a plotting suite for Oxford Nanopore sequencing data and alignments.
The output is three things. A statistical summary, a number of plots, and an HTML summary file. The statistical summary is also available as a separate NanoStats file summarizing key features of the dataset, and the HTML file is the thing you actually send around, since it carries the plots and the run information together.
The example plot in the documentation is a bivariate comparison of log transformed read length against average basecall Phred quality score, which is the canonical view for a long read run. The examples directory in the repository holds a dozen more, and the naming convention in those file names is informative on its own. You can see aligned read length against sequenced read length, mapping quality against read length, percent identity against aligned read length, and percent identity against average base quality, and each appears both with and without outliers removed and with downsampling applied. That is the range of questions the plots are built to answer.
The scope is read level quality control. There is no assembly evaluation, no variant calling and no alignment review tool here. A team that needs a full sequencing report will run this alongside other tools.
The project is also available as a web service, which is a useful option for a group that does not want to install a Python environment on every analysis machine.
The input formats it accepts
The tool performs data extraction from Oxford Nanopore sequencing data in a range of formats, and multiple files of the same type can be provided simultaneously.
The list is longer than the name suggests, and the distinctions matter in practice. Plain fastq files work, and they can be bgzip, bzip2 or gzip compressed. Fastq files generated by albacore, guppy or MinKNOW that contain additional information work too, and the documentation splits these into two distinct options further down the option list, which is covered below. Sorted bam files are accepted. The sequencing_summary.txt output table generated by albacore, guppy or MinKNOW basecalling is accepted, and it can be gzip, bz2, zip and xz compressed. Fasta files work, with the same compression options. And arrow files are accepted, described as created by other tools the author has developed.
The practical point is that NanoPlot sits at the point where basecalling has finished. Whatever your basecaller emitted, there is a good chance it is one of these, and the compression handling means you can point it at the output as it landed on disk rather than unpacking it first.
The full option list shows the same breadth on the input side, with separate flags for --fastq, --fastq_rich, --fastq_minimal, --fasta, --summary, --bam, --ubam, --cram, --pickle and --feather, and it is worth noting that --ubam is for unmapped bam files and --cram is for sorted cram files.
Installing it and the first run
Installation is a pip install of the package, and the documentation also gives the upgrade command and a conda route, with `pip install NanoPlot --upgrade` for moving to a newer version and `conda install -c bioconda nanoplot` as the alternative. The script is written for python3.
The tool is invoked as NanoPlot, and the usage line shows that an input is required and that the plot options come after it:
usage: NanoPlot [-h] [-v] [-t THREADS] [--verbose] [--store] [--raw] [--huge] [-o OUTDIR] [--no_static] [-p PREFIX] [--tsv_stats] [--info_in_report] [--maxlength N]The general options are straightforward. -t sets the allowed number of threads to be used by the script, -o specifies the directory in which output has to be created, and -p gives an optional prefix for the output files. --store keeps the extracted data in a pickle file for future plotting, and --raw stores the extracted data in a tab separated file. --no_static suppresses the static png plots, --tsv_stats outputs the stats file as a properly formatted TSV, and --info_in_report adds the NanoPlot run info into the report. --verbose writes log messages also to the terminal, and --huge tells the tool that the input data is one very large file.
A minimal invocation is therefore a set of input files, an output directory and a label, and the three flags you will reach for first are -t for threads and -o for output.
Filtering the data before you plot it
A long read run produces a lot of reads, and the filtering options are where the tool earns its place in a pipeline.
The length filters are --maxlength N, which hides reads longer than the specified length, and --minlength N, which hides reads shorter than it. --drop_outliers removes outlier reads with extreme long length, which pairs with the examples in the repository that show the same plots with and without outliers removed. --downsample N reduces the dataset to N reads by random sampling, and the example image names show the downsampled variants of the length histogram and the bivariate plots, which is the sensible way to render a scatter plot of a whole run.
The quality filters are --minqual N, which drops reads with an average quality lower than the specified value, and --percentqual, which uses qualities as theoretical percent identities rather than as Phred scores. --loglength additionally shows logarithmic scaling of lengths in the plots, which is what the example plot with the log transformed length is doing.
--runtime_until N takes only the N first hours of a run, which is how you compare the start of a sequencing run against the end. --alength uses aligned read lengths rather than sequenced length, and the documentation marks it as bam mode, which is the right flag when your reads are mapped and you care about the aligned portion.
The summary specific options are --readtype with the values 1D, 2D and 1D2, --barcoded to split the summary file by barcode, and --no_supplementary to remove supplementary alignments. The fastq_rich and fastq_minimal inputs draw the same distinction from the other side, and the documentation says fastq_minimal is extracted swiftly without elaborate checks, which is the option to reach for when the run is large and you only need the plot.
Controlling the plots and the report
The plot customisation options are the ones that change what the report looks like rather than what is in it.
The output formats are set with -f, and the accepted values are png, jpg, jpeg, webp, svg, pdf, eps and json, with the note that these are in addition to the HTML files. So the HTML report always exists and the static images are the extra.
The bivariate plots are chosen with --plots, whose values are kde, hex and dot, and there is a parallel --legacy option with the same three values for the legacy mode. --listcolors lists the colors available for plotting and exits, and --listcolormaps does the same for colormaps, which is a small thing that saves time when you are scripting a colour scheme across a set of reports.
The N50 mark in the read length histogram is toggled with --no-N50 and --N50, so you can choose whether the summary line is drawn. --title adds a title to all plots and the documentation notes it requires quoting if using spaces. --font_scale scales the font of the plots by a factor, and --dpi sets the dpi for saving images. --hide_stats removes the Pearson R stats from some bivariate plots, which is the one to reach for when the correlation coefficient on a plot is noise and it is distracting the reader.
The colour options are -c for a valid matplotlib color and -cm for a valid matplotlib colormap used for the heatmap, so the styling is matplotlib rather than something bespoke, and the listcolors and listcolormaps flags let you discover valid values instead of guessing.
Where NanoPlot is the wrong choice
The first limit is the level of analysis. This is read level quality control. If your question is whether the assembly is complete, whether the variants are real, or whether the alignment is sensible, none of that is here, and a tool like a variant caller or an assembly evaluator answers a different question.
The second is that the tool needs the data locally. The input formats are files, and while there is a web service, the analysis itself is a Python process that reads from disk. A project that keeps its sequencing data in object storage and wants plots without downloading it needs the web service or its own runner.
The third is Python version drift. The setup.py declares python_requires of 3 or greater, with classifiers listing Python 3.3, 3.4 and 3.5, and the dependency list pulls in pandas, numpy, scipy, biopython, pysam, plotly, pyarrow, kaleido, nanoget and python-dateutil. A dependency set that broad in a research tool is a maintenance consideration, and the kaleido pin in particular ties the plot export to a specific rendering stack.
The fourth is that the statistical summary and the plots are separate artefacts, and the plots are for reading while the numbers are for the report. If you need a value in a downstream pipeline, the NanoStats file is the interface, and the --tsv_stats option exists so that it is a properly formatted TSV rather than something you have to parse.
Compare that with writing the summary yourself from the same fastq. The difference in approach is that NanoPlot gives you the plots that a sequencing facility is expected to produce, in a consistent format, with the same filters applied, and a report you can send to someone who did not run it. Doing it by hand gives you exactly the numbers you want and none of the presentation.
Licence, release cadence and the checklist before you adopt it
NanoPlot is released under the MIT licence, with the licence field in the setup.py set to MIT and the classifier License :: OSI Approved :: MIT License, and the text is in the LICENSE file at the repository root. The MIT terms are permissive, with no copyleft obligation on a pipeline that calls it, and you should read the LICENSE file yourself for the exact wording.
The release history is fast. v1.47.3 came on 2026-09-01, v1.47.4 the same day, and v1.48.0 on 2026-09-05, and the current release is v1.48.0. The repository is not archived, and the last push was on 2026-10-01, so the tree is about three weeks old relative to today. A version line moving this fast in the 1.x series is normal for a research tool that tracks basecaller output changes.
The setup.py also tells you the shape of the distribution. The package name is nanoplot, the description is a plotting suite for Oxford Nanopore sequencing data and alignments, the author is Wouter De Coster, and the console script entry point is NanoPlot=nanoplot.NanoPlot:main. The packages list adds extra and scripts on top of the found packages, and the source directories are nanomath/, nanoplot/, nanoplotter/, scripts/ and extra/, with a CHANGES.md at the root.
What to check before you adopt it is short. Confirm your basecaller output is one of the accepted inputs, and if you are on guppy or MinKNOW decide between the rich and minimal fastq options based on whether the run is large. Then run it on a real run and read the HTML report rather than only looking at the plots, because the report carries the run information and the stats together. And check CHANGES.md before pinning a version, since the plot set and the defaults both move between releases.
Editorial conclusion
NanoPlot fits a sequencing group that wants a repeatable read length and basecall quality picture per run, and it fits a pipeline that already produces basecaller output in any of the supported formats and wants plots rather than just numbers. It does not fit a team that needs alignment review, variant calling or a general purpose multi-omics report, since the scope is read level quality control. Before you adopt it, confirm your basecaller output format is one of the accepted inputs, run it on a real run and read the HTML report rather than only the plots, and check the release notes, since the version line moves quickly.
Frequently asked questions
What does NanoPlot do?
It is a plotting tool for long read sequencing data and alignments that performs data extraction from Oxford Nanopore sequencing data and produces a statistical summary, a number of plots and an HTML summary file, with the summary also written as a NanoStats file.
How do I install NanoPlot?
Use pip install NanoPlot, or the conda route conda install -c bioconda nanoplot, and pip install NanoPlot --upgrade to move to a newer version. The script is written for python3 and the console command is NanoPlot.
Which input formats does NanoPlot accept?
It reads fastq files, including ones from albacore, guppy or MinKNOW with extra information, the sequencing_summary.txt table from albacore, guppy or MinKNOW, sorted bam files, cram files, fasta files and arrow files, with bgzip, bzip2, gzip, bz2, zip and xz compression supported depending on the format. Multiple files of the same type can be given at once.
Which options control the plots NanoPlot produces?
The --plots and --legacy flags choose which bivariate plots to make, from kde, hex and dot. -f sets the image output formats including png, jpg, jpeg, webp, svg, pdf, eps and json, -c and -cm set the matplotlib colour and colormap, and --title, --font_scale, --dpi, --N50 and --hide_stats adjust appearance and the annotations.
How do I filter reads before plotting with NanoPlot?
The filtering options include --maxlength and --minlength to hide reads by length, --drop_outliers for extreme long reads, --downsample to reduce the dataset to N reads, --minqual to drop reads below an average quality, --percentqual to treat qualities as percent identities, --runtime_until to take only the first N hours of a run, and --alength to use aligned rather than sequenced lengths in bam mode.
What licence does NanoPlot use?
NanoPlot is released under the MIT licence, with the licence field in the setup.py set to MIT and the text in the LICENSE file at the repository root. The current version is v1.48.0, released on 2026-09-05, and the last push was on 2026-10-01.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/wdecoster-nanoplot)Was this useful?