Skip to content

Optimise SVG plots, bump SVG line widths#188

Open
ewels wants to merge 1 commit intos-andrews:masterfrom
ewels:svg_optimise
Open

Optimise SVG plots, bump SVG line widths#188
ewels wants to merge 1 commit intos-andrews:masterfrom
ewels:svg_optimise

Conversation

@ewels
Copy link
Copy Markdown
Contributor

@ewels ewels commented Apr 15, 2026

Optimised the SVG plot outputs, reducing total SVG file size by 73% with no visual changes.

This is fairly meaningless by itself, but in the future I would love for the HTML reports to embed SVGs instead of PNGs. Then the file size of the SVGs suddenly does matter, as they're all embedded and we don't want massive HTML files.

The main improvement is for per-tile sequence quality, but there are improvements on all SVGs. Example on a 27M-read FASTQ file (ERR16944282):

SVG file Before After Reduction
adapter_content.svg 40.1 KB 10.1 KB 75%
duplication_levels.svg 6.2 KB 4.4 KB 29%
per_base_n_content.svg 13.2 KB 7.0 KB 47%
per_base_quality.svg 67.1 KB 55.3 KB 17%
per_base_sequence_content.svg 30.4 KB 9.0 KB 70%
per_sequence_gc_content.svg 25.6 KB 9.0 KB 65%
per_sequence_quality.svg 8.8 KB 5.3 KB 40%
per_tile_quality.svg 395.7 KB 👈🏻 58.4 KB 85%
sequence_length_distribution.svg 3.1 KB 2.8 KB 11%
Total 590.2 KB 161.4 KB 73%
Changes 🤖

AI summary of changes:

Shorter attributes (SVGGenerator.java)

  • Move font-family="Arial" from every <text> element to a single <style> block in the SVG header
  • Replace verbose style="fill:rgb(...);stroke:none" with fill="rgb(...)"
  • Replace style="fill:none;stroke-width:1;stroke:rgb(...)" with fill="none" stroke="rgb(...)"
  • Same for polygons and ellipses

Element merging (SVGImageSaver.java)

Post-processing applied to the SVG string before writing to disk:

  • Line → polyline: consecutive same-colour <line> segments (data series) are merged into a single <polyline> with stroke-width="2" for better visibility. Gridlines and axis lines (black/grey) are left as individual <line> elements with stroke-width="1".
  • Rect run-length encoding: consecutive same-colour <rect> elements on the same row are merged into a single wider rect. This primarily benefits the per-tile quality heatmap, which draws thousands of small rectangles.

What's not affected

  • PNG rendering is completely unchanged. PNGs are rendered via Java2D Graphics2D, which doesn't go through SVGGenerator
  • Text output (fastqc_data.txt, summary.txt) is unchanged
  • HTML report structure is unchanged (it embeds PNGs, not SVGs)

The only visual change is the thicker lines for line plots, which matches what the PNGs look like:

Before optimisation After optimisation
per_base_quality
69 KB
per_base_quality
57 KB
per_base_sequence_content
31 KB
per_base_sequence_content
9 KB
 per_tile_quality
405 KB
per_tile_quality
60 KB

Reduce SVG file sizes by:
- Moving font-family to a CSS <style> block instead of per-element attributes
- Using fill/stroke attributes instead of verbose style="..." syntax
- Merging consecutive same-colour <line> segments into <polyline> elements
- Run-length merging adjacent same-colour <rect> elements (benefits tile heatmap)
- Increasing line stroke-width to 2 for better visibility

SVG generation changes are in SVGGenerator.java (attribute format).
Post-processing optimisations are in SVGImageSaver.java (polyline/rect merging).
PNG rendering is unaffected as it uses Java2D directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ewels ewels mentioned this pull request Apr 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant