Skip to main content

multiqc-pivot

CI Python Versions basedpyright mypy Ruff

A MultiQC plugin that folds related samples into one General Statistics row per group.

Installation

pip install multiqc-pivot

Introduction

MultiQC gives every sample its own row. When one subject yields several samples that are measured by different methods, say a tumour and a normal, or two tissues and a paired-genotype check, the General Statistics table ends up with a block of half-empty rows per subject. MultiQC's own sample grouping only fills the group's row for the handful of modules that know how to merge their metrics.

This plugin runs after every module has reported and rebuilds the table:

  1. Rows for one group fold into a single row, and every folded column is prefixed by which method it came from.
  2. The original rows stay beneath the group row, so they still can be viewed.
  3. Rows for a level that does not belong in the table, such as per-library read QC, move out into their own table under General Statistics with whatever grouping they already had.
  4. Hover text, color scales, formats and hidden-by-default state carry over from the module that produced each column.

Usage

Add a sample_pivot block to any MultiQC config, for example with --config my_config.yml.

So, with these sample names:

101.subject
101.tissueA
101.tissueB
101.tissueB (filtered data, though)
101.tissueA.library.L1
101.tissueA.library.L2

This configuration produces one row named 101 carrying Concordance, TissueA Median, TissueB Median, TissueB (filtered) % Aligned and so on, and moves the library rows into a separate table:

sample_pivot:
  group: '^(?P<group>[^. ]+)\.'
  levels:
    - match: '\.subject$'
    - match: '\.(?P<analyte>tissueA|tissueB)$'
      label: '{analyte}'
    - match: '\.(?P<analyte>tissueA|tissueB) \(filtered\)$'
      label: '{analyte} (filtered)'
    - match: '\.library\.'
      table: Library statistics
  label_order: [tissueA, tissueB, tissueB (filtered)]
  tables:
    Library statistics:
      description: Per-library read QC; read pairs nest under their library.

And your report will look like:

General Statistics with one row per subject and a Library statistics table beneath it

YAML Configuration Reference

Key Meaning
group A regular expression searched in every matched sample name. Its (?P<group>...) capture names the folded row. Required.
levels An ordered list; the first level whose match is found in a sample name wins. Required.
levels[].match A regular expression searched in the sample name. Named captures are available to label.
levels[].label A format string built from the captures of match. Columns of matching rows are renamed with it and folded onto the group row; the row itself stays beneath. Omit it, and omit table, to fold the row's columns onto the group row unchanged.
levels[].table The name of a table that receives matching rows instead of General Statistics. Rows keep their grouping, so paired reads stay nested under their library. Tables sit directly under General Statistics in the order their levels are listed.
column_title How a pivoted column is titled. {label} is the label as written, {Label} has its first letter upper-cased, {title} is the module's title. Default {Label} {title}.
label_order Labels in the order their column blocks should appear. Labels not listed follow in order of first appearance.
tables Presentation of the tables named by levels[].table, currently a description each.

[!TIP] A sample that matches no level is left where it was. A sample that matches a level but not group is left alone as well, with a warning in the log. Columns that a module did not declare a header for are dropped from folded rows, as MultiQC would have dropped them anyway.

Limitations

  1. Sample names are matched after MultiQC has cleaned them, so you must write patterns against the names you see in an un-pivoted report.
  2. Only one level of nesting exists in a MultiQC table. Rows moved into a secondary table keep the nesting they already had; rows folded into a group row become its children, and cannot nest further.
  3. Two rows in the same group that resolve to the same label collide. The first value is kept and a warning is logged, so make labels specific enough to tell such rows apart.

Development and Testing

See the contributing guide for more information.

Metadata

Release files for multiqc-pivot 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for multiqc-pivot 0.1.1
File Size Uploaded
multiqc_pivot-0.1.1.tar.gz 274.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for multiqc-pivot 0.1.1
File Interpreter ABI Platform
multiqc_pivot-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 285.6 kB

Release files / multiqc_pivot-0.1.1.tar.gz

Download URL multiqc_pivot-0.1.1.tar.gz
Size 274.7 kB
Tags Source
SHA-256 checksum
How to use checksums
88e05e7c47f65f453235e41a49de8568e0bfcdf674b366e4092d4fde4020dc40
BLAKE2b-256 checksum
How to use checksums
b0d3e454eec86df8a5cf4db3dc800df41d54282150e183a22f1a469f20fa18f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.

Transparency log

Release files / multiqc_pivot-0.1.1-py3-none-any.whl

Download URL multiqc_pivot-0.1.1-py3-none-any.whl
Size 10.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f0e21f12166df50892071ca8fd78f1a232e18939d9280b0e3414c00a5d8d6f53
BLAKE2b-256 checksum
How to use checksums
569b0f1bcd3a92ddca96b2f7ab78c4b92fe03f7943e33430e9c0071b935d6979
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page