UnicodePlots.jl

repository·main·Indexed 23 days ago

https://github.com/juliaplots/unicodeplots.jl

A Julia library for high-quality plotting directly within the terminal (REPL) using Unicode characters. It provides a variety of plot types including line, scatter, bar, histogram, box, density, contour, polar, heatmap, surface, and isosurface plots. The library features a low-level Canvas API with multiple implementations such as BrailleCanvas, OctantCanvas, BlockCanvas, and AsciiCanvas to support different resolutions and terminal capabilities.

Tokens
7.5K
Snippets
19
Records
40
Agent score
77%

What's inside UnicodePlots.jl

  1. How mutating plot methods work

    main

    Many plot functions have a mutating variant ending in ! (e.g., lineplot!). These allow you to add data to an existing Plot object.

    Important: Mutating methods cannot update the axis limits because they draw onto a fixed canvas. You must set the limits beforehand when creating the initial Plot object or using the non-mutating constructor.

  2. Understand Canvas types

    main

    The core of UnicodePlots is the Canvas abstraction. Different canvas types provide different resolutions and rendering styles:

    • BrailleCanvas: Highest resolution; uses Unicode Braille symbols (8 pixels per character).
    • BlockCanvas: Medium resolution; uses Unicode blocks (4 pixels per character).
    • HeatmapCanvas: Lower resolution; uses foreground/background colors (2 pixels per character).
    • AsciiCanvas / DotCanvas: Uses standard ASCII characters; best for file output or environments with font issues.
    • DensityCanvas: Tracks pixel frequency per character to visualize data density.
    • BarplotGraphics: Specialized for barplots; does not support pixel manipulation, only addrow! for adding bars.
    import UnicodePlots: lines!, points!, pixel!
    canvas = BrailleCanvas(15, 40,                    # number of rows and columns (characters)
                             origin_y=0., origin_x=0.,  # position in virtual space
                             height=1., width=1.)       # size of the virtual space
    lines!(canvas, 0., 0., 1., 1.; color=:cyan)       # virtual space
    points!(canvas, rand(50), rand(50); color=:red)   # virtual space
    lines!(canvas, 0., 1., .5, 0.; color=:yellow)     # virtual space
    pixel!(canvas, 5, 8; color=:red)                  # pixel space
    Plot(canvas)
  3. Choose the appropriate Canvas type for your plot

    main

    Depending on your resolution and terminal support requirements, you can choose from several Canvas implementations:

    Canvas TypeDescription
    BrailleCanvasHigh resolution. Uses Braille symbols where each character represents 8 pixels via binary operations.
    OctantCanvasHigh resolution. Uses Unicode octant symbols (8 pixels per character). Requires Unicode 16 support (released 2024).
    BlockCanvasMedium resolution. Uses block characters where each character represents 4 pixels. Pixels have no visible spacing.
    HeatmapCanvasLow resolution. Uses foreground and background terminal colors to represent 2 color pixels per character. The number of rows is half the number of y coordinates.
    AsciiCanvasLow resolution. Uses standard ASCII characters. Best for environments with limited Unicode support or when printing to files.
    DotCanvasLow resolution. Uses standard ASCII characters.
    DensityCanvasInstead of marking pixels, it increments a counter per character to track pixel frequency, allowing for density-based data visualization.
    BarplotGraphicsA special graphics area for barplots that does not support pixel manipulation. It only supports the addrow! method to add bars.
  4. Configure 3D Plot Views

    main

    3D plots use a Model-View-Projection (MVP) transformation. You can control the camera using the following keywords:

    • elevation: Angle above/below the floor plane ($-90 ≤ θ ≤ 90$).
    • azimuth: Azimuthal angle around the up vector ($-180^° ≤ φ ≤ 180^°$).
    • up: The up vector (:x, :y, or :z). Prefix with m or p to change the sign (e.g., :mz for $-z$).
    • zoom: Zooming factor.

    Other 3D options:

    • projection: Set to :persp(ective) or :ortho(graphic).
    • axes3d: Boolean to display $x$, $y$, and $z$ axes.
    • near / far: Clipping plane distances (for :perspective only).
  5. Quickstart with UnicodePlots

    main

    To create a basic line plot, use the lineplot function. You can provide x and y coordinates, along with metadata like title, name (for the series), and axis labels.

    For better results when printing to a file, you can specify different Canvas types like AsciiCanvas, DotCanvas, or BlockCanvas using the canvas keyword.

    using UnicodePlots
    lineplot([-1, 2, 3, 7], [-1, 2, 9, 4], title="Example", name="my line", xlabel="x", ylabel="y")
    
    # Using a different canvas for file output
    plt = lineplot([-1, 2, 3, 7], [-1, 2, 9, 4], title="Example", name="my line",
                     xlabel="x", ylabel="y", canvas=DotCanvas, border=:ascii)
  6. Get started with UnicodePlots.jl

    main

    A basic line plot can be created using the lineplot function. You can provide title, name (for the legend), and axis labels using xlabel and ylabel.

    using UnicodePlots
    lineplot([-1, 2, 3, 7], [-1, 2, 9, 4], title="Example", name="my line", xlabel="x", ylabel="y")
  7. Create complex layouts with gridplot

    main

    While UnicodePlots integrates with Plots.jl for basic layouts, complex grids require the gridplot function and the Term.jl package.

    Use UnicodePlots.panel() to wrap individual plots before combining them with arithmetic operators (*, /) or using gridplot().

    Example using arithmetic operators:

    using UnicodePlots, Term
    
    (UnicodePlots.panel(lineplot(1:2)) * UnicodePlots.panel(scatterplot(rand(100)))) /
    (UnicodePlots.panel(lineplot(2:-1:1)) * UnicodePlots.panel(densityplot(randn(1_000), randn(1_000))))

    Example using gridplot:

    # Grid with specific layout
    gridplot(map(i -> lineplot(-i:i), 1:3); layout=(2, nothing))
    
    # Grid with placeholders
    gridplot(map(i -> lineplot(-i:i), 1:5); show_placeholder=true)
    using UnicodePlots, Term
    
    (
      UnicodePlots.panel(lineplot(1:2)) *
      UnicodePlots.panel(scatterplot(rand(100)))
    ) /
    (
      UnicodePlots.panel(lineplot(2:-1:1)) *
      UnicodePlots.panel(densityplot(randn(1_000), randn(1_000)))
    )
  8. Save plots as PNG or TXT

    main

    You can save plots using the savefig command.

    • TXT: Supported by default.
    • PNG: Experimental. Requires import FreeType, FileIO to be called before loading UnicodePlots.

    To recover a plot as a string containing ANSI color codes, use string(p; color=true).

  9. Configure plot dimensions and axes

    main

    You can customize the appearance and orientation of your plots using several keywords:

    • Dimensions: Use height=:auto and/or width=:auto to match the current terminal size. When using width=:auto, it is recommended to set compact=true to maximize the plot size.
    • Flipping: Use xflip=true and/or yflip=true to reverse/flip the axes.
    • Canvas Types: Use canvas=DotCanvas, canvas=AsciiCanvas, or canvas=BlockCanvas for different rendering styles.