drawIt

Terminal User Interface (TUI) for drawing plots and shapes in the terminal

Pure Nim score 15/100 · tests present · no docs generated

Summary

Latest Version 0.6.3
License MIT
CI Status Failing
Downloads 0
Last Indexed 2026-07-21 05:25

Authors

  • Oliver Thomas

Installation

nimble install drawIt
choosenim install drawIt
git clone https://gitlab.com/OFThomas/drawIt

OS Compatibility

Platform Linux macOS Windows FreeBSD OpenBSD NetBSD Android iOS WASM Embedded
drawIt - - - - - - -

Dependencies

Package Version Optional
nim >= 1.6.10 No
nimpy - No
nimpng - No

Source

Repository https://gitlab.com/OFThomas/drawIt
Homepage https://gitlab.com/OFThomas/drawIt
Registry Source nimble_official

README

drawIt

You can install with

nimble install drawit

Contents

  • Part 1 Plots
  • Part 2 Terminal user interface

Plots

There are three main procs,

To use unicode quad blocks (very bright/bold figures):

plot(data: openArray[T])

To make connected wiggly lines:

plotWiggle[T](data: openArray[T])

and to use the highest resolution using unicode Braille characters (lots of dots):

plotHD[T](data: openArray[T])

To build the python wrappers

from the src/drawItpkg directory, to compile the python bindings as a shared object

nim c --app:lib --out:drawit.so --threads:on drawit

Then you can run pytest.py!

Examples

import drawIt/graphs
import sequtils
import random

var data = newSeq[float](40)
data.applyit(rand(1.0))
echo data.plotWiggle
echo data.plotHD
0.99     ╭╮     ╭╮               ╭╮  ╭╮      
0.92     ││     ││╭╮       ╭╮    ││  │╰╮ ╭╮  
0.86     ││╭╮   ││││  ╭╮ ╭╮│╰╮   ││    ││  
0.79 ┤╮   ││││   │││╰╮ ││ │╰╯    │╰╮   ││  
0.73 ┤│╭╮ ││││   │││  ││           ││  
0.66 ┤│││ ││││   │││  ││           ││  
0.60 ┤│││╭╯│││   │││ ╰╮│╰╮│          ││  
0.53 ┤││││ ││╰╮ ╭╯││  ││ ││   ╰╮   ╰╮│  ││  
0.47 ┤││││ ││   ││  ││ ││    ╰╮   ││ │╭╯│  
0.40 ┤││││ ╰╯   ││  ││ ││        ││ ││   
0.34 ┤││││    │╭╯ ││  ╰╯ ││        ││ ││   
0.27 ┤││││    ││  ││     ││        ╰╯ ││   
0.21 ┤╰╯││    ╰╯  ││     ││           ││ ╰╮ 
0.14   ││        ││     ╰╯           ╰╯   
0.07   ││        ╰╯            ╰─╯         ╰─
0.01   ╰╯                                    
      ________________________________________
      0.0      10.0      20.0      30.0      40.0

0.99 ┤⠀⠀⣀⠀⠀⢰⡆⠀⠀⠀⠀⠀⠀⠀⣿⠀⣀⠀⠀⠀
0.92 ┤⠀⠀⣿⠀⠀⢸⡇⠀⠀⠀⠀⣶⠀⠀⣿⠀⣿⡀⣤⠀
0.86 ┤⠀⠀⣿⣀⠀⢸⣿⡇⠀⠀⣤⣿⡀⠀⣿⠀⡇⡇⣿⠀
0.79 ┤⡄⠀⣿⣿⠀⢸⣿⢧⢸⡇⡟⠃⡇⠀⡟⡆⡇⡇⣿⠀
0.73 ┤⡇⠀⣿⣿⠀⢸⣿⢸⢸⡇⡇⠀⡇⠀⡇⡇⡇⡇⣿⠀
0.66 ┤⣿⡇⣿⣿⠀⢸⣿⢸⢸⡇⡇⠀⡇⠀⡇⡇⡇⡇⣿⠀
0.60 ┤⣿⣇⣿⣿⠀⢸⣿⢸⣸⣇⡇⠀⡇⠀⡇⡇⡇⡇⣿⠀
0.53 ┤⣿⣿⢸⣿⠀⡼⣿⠀⣿⢸⡇⠀⡇⠀⡇⣇⡇⡇⣿⠀
0.47 ┤⣿⣿⢸⡟⡆⡇⣿⠀⣿⢸⡇⠀⠹⡄⡇⢸⡇⣧⢿⠀
0.40 ┤⣿⣿⠘⠃⡇⡇⣿⠀⣿⢸⡇⠀⠀⡇⡇⢸⡇⣿⢸⠀
0.34 ┤⣿⣿⠀⠀⣇⡇⣿⠀⠛⢸⡇⠀⠀⡇⡇⢸⡇⣿⢸⠀
0.27 ┤⣿⣿⠀⠀⣿⠀⣿⠀⠀⢸⡇⠀⠀⡇⡇⢸⡇⣿⢸⠀
0.21 ┤⣿⣿⠀⠀⣿⠀⣿⠀⠀⢸⡇⠀⠀⡇⡇⠈⠁⣿⠘⡆
0.14 ┤⠉⣿⠀⠀⠉⠀⣿⠀⠀⢸⡇⠀⠀⡇⡇⠀⠀⠿⠀⡇
0.07 ┤⠀⣿⠀⠀⠀⠀⣿⠀⠀⠈⠁⠀⠀⠧⠇⠀⠀⠀⠀⠓
0.01 ┤⠀⣿⠀⠀⠀⠀⠛⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
      ____________________
      0.0  10.0  20.0  30.0  40.0

Or a sine wave,

import drawIt/graphs
import sequtils
from std/math import sin

var x: seq[float]
const maxnum = 80
for i in 0 ..< maxnum:
    x.add i.float

let data = x.mapit(sin(it/4.0))
echo data.plotWiggle
echo data.plotHD
 1.00 ┤    ╭──╮                     ╭──╮                      ╭─╮                      
 0.86 ┤   ╭╯  ╰╮                   ╭╯  ╰╮                    ╭╯ ╰─╮                    
 0.73 ┤   │    ╰╮                  │    ╰╮                  ╭╯    │                  ╭─
 0.60 ┤  ╭╯     ╰╮                ╭╯     ╰╮                ╭╯     ╰╮                ╭╯ 
 0.46 ┤ ╭╯       │               ╭╯       │                │       ╰╮               │  
 0.33 ┤ │        ╰╮              │        ╰╮              ╭╯        │              ╭╯  
 0.20 ┤╭╯         │             ╭╯         │              │         ╰╮             │   
 0.07 ┤│          ╰╮            │          ╰╮            ╭╯          │            ╭╯   
-0.07 ┤╯           │           ╭╯           │            │           ╰╮           │    
-0.20 ┤            ╰╮          │            ╰╮          ╭╯            │          ╭╯    
-0.33 ┤             │         ╭╯             │         ╭╯             ╰╮         │     
-0.47 ┤             ╰╮        │              ╰╮        │               │        ╭╯     
-0.60 ┤              │       ╭╯               ╰╮      ╭╯               ╰╮       │      
-0.73 ┤              ╰╮      │                 │      │                 │      ╭╯      
-0.87 ┤               ╰╮    ╭╯                 ╰╮    ╭╯                 ╰╮    ╭╯       
-1.00 ┤                ╰────╯                   ╰────╯                   ╰────╯        
       ________________________________________________________________________________
       0.0      10.0      20.0      30.0      40.0      50.0      60.0      70.0      80.0

 1.00 ┤⠀⠀⡼⢹⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠏⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡼⠹⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
 0.86 ┤⠀⢰⠃⠀⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⡼⠀⠸⡄⠀⠀⠀⠀⠀⠀⠀⠀⢠⠇⠀⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀
 0.73 ┤⠀⡼⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⢀⡇⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⢸⡀⠀⠀⠀⠀⠀⠀⠀⠀⡇
 0.60 ┤⠀⡇⠀⠀⠘⡆⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⢹⠀⠀⠀⠀⠀⠀⠀⠀⡏⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⢰⠃
 0.46 ┤⢰⠃⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⡼⠀⠀⠀⢸⡀⠀⠀⠀⠀⠀⠀⢠⠇⠀⠀⠀⢧⠀⠀⠀⠀⠀⠀⠀⣸⠀
 0.33 ┤⢸⠀⠀⠀⠀⢹⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⡇⠀
 0.20 ┤⡏⠀⠀⠀⠀⢸⡀⠀⠀⠀⠀⠀⢰⠃⠀⠀⠀⠀⢧⠀⠀⠀⠀⠀⠀⡼⠀⠀⠀⠀⠘⡆⠀⠀⠀⠀⠀⢀⡇⠀
 0.07 ┤⡇⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⢸⠀⠀
-0.07 ┤⠁⠀⠀⠀⠀⠀⣇⠀⠀⠀⠀⠀⡞⠀⠀⠀⠀⠀⠸⡄⠀⠀⠀⠀⢠⠇⠀⠀⠀⠀⠀⢳⠀⠀⠀⠀⠀⣸⠀⠀
-0.20 ┤⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⡇⠀⠀
-0.33 ┤⠀⠀⠀⠀⠀⠀⢸⡀⠀⠀⠀⢰⠃⠀⠀⠀⠀⠀⠀⢧⠀⠀⠀⠀⡼⠀⠀⠀⠀⠀⠀⠘⡆⠀⠀⠀⢀⡇⠀⠀
-0.47 ┤⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⢸⠀⠀⠀
-0.60 ┤⠀⠀⠀⠀⠀⠀⠀⢧⠀⠀⠀⡏⠀⠀⠀⠀⠀⠀⠀⠘⡆⠀⠀⢰⠃⠀⠀⠀⠀⠀⠀⠀⢹⠀⠀⠀⡼⠀⠀⠀
-0.73 ┤⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⢀⡇⠀⠀⠀⠀⠀⠀⠀⠀⣇⠀⠀⣸⠀⠀⠀⠀⠀⠀⠀⠀⢸⡀⠀⠀⡇⠀⠀⠀
-0.87 ┤⠀⠀⠀⠀⠀⠀⠀⠈⡇⠀⣸⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⢸⠁⠀⠀⠀
-1.00 ┤⠀⠀⠀⠀⠀⠀⠀⠀⢳⣀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣇⣸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣀⡞⠀⠀⠀⠀
       ________________________________________
       0.0  10.0  20.0  30.0  40.0  50.0  60.0  70.0  80.0

Multiplot support

 1000.00 ┤                   ╭─ 1000.00 ┤         ▐▘ 1000.00 ┤⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠁
  714.29 ┤                  ╭╯   714.29 ┤         ▛   714.29 ┤⠀⠀⠀⠀⠀⠀⠀⠀⠀⡏⠀
  428.57 ┤                 ╭╯    428.57 ┤        ▟▘   428.57 ┤⠀⠀⠀⠀⠀⠀⠀⠀⣸⠁⠀
  142.86 ┤              ╭──╯     142.86 ┤      ▗▟▘    142.86 ┤⠀⠀⠀⠀⠀⠀⢀⡴⠃⠀⠀
 -142.86 ┤    ╭─────────╯       -142.86 ┤  ▄▛▀▀▀     -142.86 ┤⠀⢀⡴⠋⠉⠉⠉⠀⠀⠀⠀
 -428.57 ┤  ╭─╯                 -428.57 ┤ ▟▘         -428.57 ┤⠀⡞⠀⠀⠀⠀⠀⠀⠀⠀⠀
 -714.29 ┤ ╭╯                   -714.29 ┤▐▘          -714.29 ┤⢸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀
-1000.00 ┤─╯                   -1000.00 ┤▛          -1000.00 ┤⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
          _____________________          __________________          __________________
          0.0     10.0     20.0          0.0  10.0  20.0          0.0  10.0  20.0

 1000.00 ┤                   ╭─ 1000.00 ┤         ▐▘ 1000.00 ┤⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠁
  714.29 ┤                  ╭╯   714.29 ┤         ▛   714.29 ┤⠀⠀⠀⠀⠀⠀⠀⠀⠀⡏⠀
  428.57 ┤                 ╭╯    428.57 ┤        ▟▘   428.57 ┤⠀⠀⠀⠀⠀⠀⠀⠀⣸⠁⠀
  142.86 ┤              ╭──╯     142.86 ┤      ▗▟▘    142.86 ┤⠀⠀⠀⠀⠀⠀⢀⡴⠃⠀⠀
 -142.86 ┤    ╭─────────╯       -142.86 ┤  ▄▛▀▀▀     -142.86 ┤⠀⢀⡴⠋⠉⠉⠉⠀⠀⠀⠀
 -428.57 ┤  ╭─╯                 -428.57 ┤ ▟▘         -428.57 ┤⠀⡞⠀⠀⠀⠀⠀⠀⠀⠀⠀
 -714.29 ┤ ╭╯                   -714.29 ┤▐▘          -714.29 ┤⢸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀
-1000.00 ┤─╯                   -1000.00 ┤▛          -1000.00 ┤⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
          _____________________          __________________          __________________
          0.0     10.0     20.0          0.0  10.0  20.0          0.0  10.0  20.0

 1000.00 ┤                   ╭─ 1000.00 ┤         ▐▘ 1000.00 ┤⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠁
  714.29 ┤                  ╭╯   714.29 ┤         ▛   714.29 ┤⠀⠀⠀⠀⠀⠀⠀⠀⠀⡏⠀
  428.57 ┤                 ╭╯    428.57 ┤        ▟▘   428.57 ┤⠀⠀⠀⠀⠀⠀⠀⠀⣸⠁⠀
  142.86 ┤              ╭──╯     142.86 ┤      ▗▟▘    142.86 ┤⠀⠀⠀⠀⠀⠀⢀⡴⠃⠀⠀
 -142.86 ┤    ╭─────────╯       -142.86 ┤  ▄▛▀▀▀     -142.86 ┤⠀⢀⡴⠋⠉⠉⠉⠀⠀⠀⠀
 -428.57 ┤  ╭─╯                 -428.57 ┤ ▟▘         -428.57 ┤⠀⡞⠀⠀⠀⠀⠀⠀⠀⠀⠀
 -714.29 ┤ ╭╯                   -714.29 ┤▐▘          -714.29 ┤⢸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀
-1000.00 ┤─╯                   -1000.00 ┤▛          -1000.00 ┤⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
          _____________________          __________________          __________________
          0.0     10.0     20.0          0.0  10.0  20.0          0.0  10.0  20.0

Colour Support

Only in the terminal using ASCII escape codes.

import drawIt/graphs
import sequtils
from std/math import pow

var x: seq[float]
const maxnum = 21
for i in 0 ..< maxnum:
  x.add -(maxnum div 2).float + i.float

var y = x.mapit(it.pow(3))

for color in TermColor:
  echo draw(
      y.plot(resolution = 8, pltCol = color),
      y.plotWiggle(resolution = 8, pltCol = color),
      y.plotHD(resolution = 8, pltCol = color)
  )

Coloured multiplots Coloured multiplots

Side by side and multiple values on a single plot

import drawIt/graphs
import sequtils
from std/math import pow

template drawAndMultiExample(pltStyle: untyped) = 

  var x: seq[float]
  const maxnum = 21
  for i in 0 ..< maxnum:
    x.add -(maxnum div 2).float + i.float

  var plots: seq[Plot]

  for i in 1 .. 3:
    plots.add x.mapit((it.pow(i.float))/10.pow(i.float)).pltStyle(x = x, pltCol = TermColor.toSeq[i])

  draw(plots).echo
  multiplot(plots).echo


plotWiggle.drawAndMultiExample

wiggle block braille

Animations

Every plot display procedure can be called with echo which prints the whole plot to stdout, or the animate proc which draws it line by line to std out, for a cool looking print. animated

2D Contour/Surface plots

They are avaliable using the proc:

plot2D(data)

2dLorentzian

import drawItpkg/graphs
import sequtils
import math
block:
    const minvals = 3.0
    const numPoints = 20
    let X = linspaced[float](-minvals, minvals, 2*numPoints)
    let Y = linspaced[float](-minvals, minvals, numPoints)

    var data: seq[float]
    for y in Y:
      for x in X:
        data.add Lorentz2D(x,y)

    data.plot2D(X.len)

2dGaussian

import drawItpkg/graphs
import sequtils
import math

block:
    const minvals = 3.0
    const numPoints = 20
    let X = linspaced[float](-minvals, minvals, 2*numPoints)
    let Y = linspaced[float](-minvals, minvals, numPoints)

    var data: seq[float]
    for y in Y:
      for x in X:
        data.add Gauss2D(x,y)

    data.plot2d(X.len)

sin2xsin2y

import drawItpkg/graphs
import sequtils
import math

block:
    const minvals = 3.0
    const numPoints = 20
    let X = linspaced[float](-minvals, minvals, 2*numPoints)
    let Y = linspaced[float](-minvals, minvals, numPoints)

    var data: seq[float]
    for y in Y:
      for x in X:
        data.add sin(2*x) * sin(2*y)

    data.plot2D(X.len, ColorScheme.blueblackred)

2dLorentzsine

import drawItpkg/graphs
import sequtils
import math

block:
    const minvals = 3.0
    const numPoints = 20
    let X = linspaced[float](-minvals, minvals, 2*numPoints)
    let Y = linspaced[float](-minvals, minvals, numPoints)

    var data: seq[float]
    for y in Y:
      for x in X:
        data.add sin(10*x) * sin(5*y) * Lorentz2D(x,y)

    data.plot2D(X.len, ColorScheme.blueblackred)

The Terminal User Interface

Currently not stable AT ALL, the binary is installed with nimble, you can run

drawittui

to launch the test/examples program.

There a bunch of different widgets I've been working on, here's a gif. tuigif