Universe

Visualize Neural Network Architectures in high-quality diagrams using Typst, with style and API inspired by PlotNeuralNet.

Static Badge  GitHub Release  GitHub License  GitHub Repo stars

Example of Neural Net visualizaiton with cold color palette Example of Neural Net visualizaiton with warm color palette

Under the hood, this package only uses the native Typst package CeTZ for building the diagrams.

Usage

Simply import the all-in-one drawing function from the neural-netz package:

#import "@preview/neural-netz:0.3.0": draw-network

You can then call draw-network which has the following arguments:

#draw-network(
  layers,
  connections: (),
  palette: "warm",
  show-legend: false,
  legend-title: "Layers",
  scale: 100%,
  stroke-thickness: 1,
  depth-multiplier: 0.3,
  show-relu: false,
)

See the examples in the following section to understand how to use it. Alternatively, you can also start from already written architecture examples (see the Examples section, near the end).

Getting started

Here are a few simple features for getting started.

Basic layout

#draw-network((
    (type: "input", image: "default"),
    (type: "conv", offset: 2), // Next layers are automatically connected with arrows
    (type: "conv", offset: 2),
    (type: "pool"), // Pool layers are sticked to previous convolution block (by default))
    (type: "conv", widths: (1, 1), offset: 3) // you can offset layers
))

Basic layout example

For the input type layer, you can also specify a custom image by giving image: image("path/to/your/image.jpg"). Additionally not giving any image is equivalent to giving image: none.

Dimensions and labels

#draw-network((
    (
      type: "convres", // Each layer type has its own color
      widths: (1, 2),
      channels: (32, 64, 128), // An extra channel will be used as diagonal axis label
      height: 6,
      depth: 8,
      label: "residual convolution",
    ),(
      type: "pool",
      channels: ("", "text also works"),
      height: 4,
      depth: 6,
      connection-label: "connection label", // label of the connection to the NEXT layer
    ),(
      type: "conv",
      widths: (1.5, 1.5),
      height: 2,
      depth: 3,
      label: "whole block label",
      legend: "CUSTOM NAME", // you can overwrite the default legend of predefined layers
      offset: 4,
    ),(
      type: "fc",
      channels: (10,),
      height: 5,
      depth: 0, // With no depth, the layer is drawn as a 2D rectangle
      label: "2D layer",
      offset: 2,
    ),
),
show-legend: true,
)

Dimensions and labels example

Using show-legend: true you can add a smart legend to your visual !

And if you network does not fit the page width of your Typst document, you can reduce the scale by giving scale: 50% as argument of draw-network (adjust the scale value to your need).

Adding other connections

The main axis connections are drawn automatically, except for the input layer. You can overwrite that by using the boolean show-connection to tell if the connection after a layer should be drawn or not. You can also draw extra connections using the connections argument of draw-network. In order to make reference to a layer, it will need a name:

#draw-network((
  (type: "input", label: "A", name: "a", show-connection: true),
  (type: "conv", label: "B", name: "b", offset: 2),
  (type: "conv", label: "C", name: "c", offset: 2),
  (type: "conv", label: "D", name: "d", offset: 2, show-connection: false),
  (type: "conv", label: "E", name: "e", offset: 2),
), connections: (
  (from: "a", to: "c", type: "skip", mode: "depth", label: "depth mode", pos: 6),
  (from: "b", to: "d", type: "skip", mode: "flat", label: "flat mode", pos: 5),
  (from: "c", to: "e", type: "skip", mode: "air", label: "air mode (+touch layer instead of arrow)", pos: 5, touch-layer: true),
),
palette: "cold", // There is a "warm" and a "cold" color palette.
show-relu: true // visualize relu using darker color on convolution layers
)

Adding connections example

Predefined layer types

Here is a visualization of all the predefined layer types, in both color palettes available ("warm" (default) and "cold"). You can find their associated name underneath each layer. Of course, this is just a starting point, you can modify most of their default attributes.

Predefined layers example

code for this image

Custom layers

If you prefer to create you own type of layers, use type: "custom" as a starting point. It is a generic layer, that is easily customizable. It can have one or multiple channels, with an optional “bandfill” color for symbolizing activation functions (e.g. ReLU). Note that the visiblity of activations can be set with the boolean show-relu at the draw-network scale, and can be overwritten on a per-layer basis.

A custom layer can also be added to the smart legend, when specifying a legend label (no need to specify the legend everytime for the same-colored custom layers).

#draw-network((
  (
    type: "custom",
    width: 0.3, height: 5, depth: 5,
    label: "custom..",
    fill: rgb("#FF6B6B"),
    opacity: 0.9,
    legend: "Custom Color",
  ),(
    type: "custom",
    width: 0.3, height: 5, depth: 5,
    label: "..colors !",
    fill: rgb("#FF6B6B"),
    opacity: 0.9,
    offset: 1.7,
    image: [hi] // Add any content (image, text etc.)
  ),(
    type: "custom",
    widths: (0.3, 0.4, 0.3), height: 5, depth: 5,
    label: "custom color+bandfill", 
    fill: rgb("#4ECDC4"),
    bandfill: rgb("#FFE66D"),
    show-relu: true,
    offset: 2,
    legend: "Custom Color+Bandfill",
  ),
),
show-legend: true,
legend-title: "My new layers" // You can also change the legend title
)

Custom layer example

Examples

Here are a few network architectures implemented with neural-netz (more examples can be found in the repo).

ResNet18

ResNet18 visualization

code for this image

U-Net

U-Net visualization

code for this image

FCN-8

FCN-8 visualization

code for this image

Cite this work

If you use the neural-netz package for a scientific publication, you can cite its initial publication on HAL, indicating current version as follows:

APA

Remy, E. (2025). neural-netz, a Typst Package (Version 0.3.0) [Computer software]. https://hal.science/hal-05401124

BibTeX

@softwareversion{remy:hal-05401124v1,
  TITLE = {{neural-netz, a Typst Package}},
  AUTHOR = {Remy, Edgar},
  URL = {https://hal.science/hal-05401124},
  NOTE = {},
  YEAR = {2025},
  MONTH = Dec,
  SWHID = {swh:1:dir:c0d8294e6b01cdb5bc8703eeb51e546275244c0a;origin=https://github.com/edgaremy/neural-netz;visit=swh:1:snp:052f4efa29f793bf84901593b27254f2e0e15ffb;anchor=swh:1:rev:3669d7922f3581afc2da1f12b9e62c54e4242048},
  VERSION = {0.3.0},
  REPOSITORY = {https://github.com/edgaremy/neural-netz},
  LICENSE = {https://spdx.org/licenses/MIT-0},
  KEYWORDS = {visualization ; typst ; neural networks ; deep learning},
  HAL_ID = {hal-05401124},
  HAL_VERSION = {v1},
}

Acknowledgements

This package could not have existed without the great Python+LaTeX visualization package PlotNeuralNet made by Haris Iqbal. It proposes an elegant way for viewing neural networks, and its visual style was obviously a strong inspiration for the implementation of neural-netz.

Default input image was taken from iNaturalist (colors are slightly edited).

If you feel like contributing to this package (bug fixes, features or even code refactoring), or want your model added to the model gallery, feel free to make a PR to the neural-netz repo :)