💾 Archived View for eluum.net › gemlog › 2023-11-24-julia-plots.gmi captured on 2024-08-31 at 11:24:49. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-12-28)
-=-=-=-=-=-=-
Having recently discovered gemini, I have been trying to think about what kind content I could contribute. I was slightly concerned about the lack of embedded images, as I generally like to do technical stuff with visualizations, but then I remembered something I had read in the Julia Plots documentation a while back and got an idea.
Julia is an open source programming language for scientific computing. It takes inspiration from matlab, python, and lisp (even though it isn't written with s expressions).
The Julia Programming Language
One interesting thing about Julia is that the plotting library, called Plots, can render figures using multiple backends. This is useful because the same figure can be embedded in a webpage, or saved to a variety of image formats. What caught my interest with respect to gemini is the UnicodePlots backend, which renders figures using unicode for display in terminals. This should be perfect for gemini articles!
Here is a simple line plot example.
using Plots using UnicodePlots # set the backend to use UnicodePlots unicodeplots() # sine wave plot plot(range(0, 2π, 100), sin) ┌────────────────────────────────────────┐ 1.05987 │⠀⡇⠀⠀⠀⠀⠀⠀⡠⠴⠒⠢⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ y1 │⠀⡇⠀⠀⠀⠀⢠⠚⠀⠀⠀⠀⠀⠑⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⡇⠀⠀⠀⡠⠃⠀⠀⠀⠀⠀⠀⠀⠈⢢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⡇⠀⠀⡰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⡇⠀⡰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⡇⡰⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⣧⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠤⡯⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠼⡤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⡤⠤│ │⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠃⠀│ │⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠱⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠊⠀⠀│ │⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠣⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠎⠀⠀⠀│ │⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢣⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠎⠀⠀⠀⠀│ │⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠱⡀⠀⠀⠀⠀⠀⠀⠀⢠⠊⠀⠀⠀⠀⠀│ │⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢄⠀⠀⠀⠀⠀⡤⠊⠀⠀⠀⠀⠀⠀│ -1.05987 │⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⠢⠤⠖⠊⠀⠀⠀⠀⠀⠀⠀⠀│ └────────────────────────────────────────┘ ⠀-0.188496⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀6.47168⠀
Wow! Who even needs Jupyter notebooks. The documentation covers a variety of plot types that are available. Here is a contour plot.
# define surface function pole(x, y, z, ϵ) = 1 ./ (abs.(x + y*im - z) + ϵ) surface(x, y) = pole(x, y, 0.5 + 0.75im, 0.1) + pole(x, y, 0.25 + 0.25im, 0.2) # create contour plot contour(range(0, 1, 100), range(0, 1, 100), surface, xlabel = "real", ylabel = "imaginary", levels = 10) ┌────────────────────────────────────────┐ 10 1 │⠀⠀⣠⠚⠁⠀⠀⠀⠀⠀⢀⠤⠚⠉⠁⠀⢀⣀⣀⣀⣀⣀⣀⠀⠀⠉⠒⢄⡀⠀⠀⠀⠀⠘⢦⡀⠀⠀⠀⠀│ ┌──┐ │⣠⠎⠁⠀⠀⠀⠀⠀⡠⠎⠁⠀⢀⡠⠔⠉⣁⡠⠤⠤⠤⠤⣀⡉⠑⠦⡀⠀⠈⠢⡀⠀⠀⠀⠀⠱⡄⠀⠀⠀│ │▄▄│ │⠁⠀⠀⠀⠀⠀⢠⠞⠁⠀⠀⡰⠊⠀⡴⠊⡥⢒⣮⣭⣭⣵⡲⣍⠲⡄⠘⢦⠀⠀⠘⡄⠀⠀⠀⠀⠸⡄⠀⠀│ │▄▄│ │⠀⠀⠀⠀⠀⢠⠋⠀⠀⠀⣰⠁⠀⡜⠀⡞⢰⢱⣽⣿⣿⣯⡟⡎⡇⢸⠀⠈⡇⠀⠀⢹⠀⠀⠀⠀⠀⢣⠀⠀│ │▄▄│ │⠀⠀⠀⠀⢠⠇⠀⠀⠀⠀⡇⠀⠀⢧⠀⠣⡘⢬⣺⠿⠿⣟⠵⣡⠃⡸⠀⠀⡇⠀⠀⢸⠀⠀⠀⠀⠀⢸⠀⠀│ │▄▄│ │⠀⠀⠀⢀⡎⠀⠀⠀⠀⠀⡇⠀⠀⠈⢢⡀⠙⠒⠬⠭⠭⠖⠊⣁⠔⠁⢀⡞⠀⠀⠀⡞⠀⠀⠀⠀⠀⢸⠀⠀│ │▄▄│ │⠀⠀⢀⡜⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠈⠑⠒⠢⠔⠒⠒⠉⠁⢀⡴⠋⠀⠀⠀⡼⠁⠀⠀⠀⠀⠀⡇⠀⠀│ │▄▄│ imaginary │⠀⠀⡜⠀⠀⠀⠀⠀⠀⡴⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠤⠖⠁⠀⠀⠀⢠⠞⠀⠀⠀⠀⠀⠀⡼⠀⠀⠀│ │▄▄│ │⠀⡜⠀⠀⠀⠀⢀⡴⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠖⠊⠁⠀⠀⠀⠀⢀⡔⠁⠀⠀⠀⠀⠀⠀⡸⠁⠀⠀⠀│ │▄▄│ │⢰⠁⠀⠀⠀⡰⠃⠀⠀⢀⣀⡀⠀⠀⠀⠀⠀⡸⠁⠀⠀⠀⠀⠀⠀⡴⠉⠀⠀⠀⠀⠀⠀⢀⡜⠁⠀⠀⠀⠀│ │▄▄│ │⢸⠀⠀⠀⢰⠁⠀⡰⠋⢁⣀⠉⠳⡀⠀⠀⢠⠇⠀⠀⠀⠀⠀⡴⠋⠀⠀⠀⠀⠀⠀⠀⣠⠊⠀⠀⠀⠀⠀⠀│ │▄▄│ │⠘⡄⠀⠀⠸⡄⠀⢣⡀⠣⠼⢀⡰⠃⠀⢀⠎⠀⠀⠀⠀⣠⠎⠀⠀⠀⠀⠀⠀⠀⢀⠜⠁⠀⠀⠀⠀⠀⠀⠀│ │▄▄│ │⠀⠘⢆⠀⠀⠘⠢⢄⡈⠉⠉⠉⣀⡤⠔⠁⠀⠀⢀⡠⠚⠁⠀⠀⠀⠀⠀⠀⢀⠔⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │▄▄│ │⠀⠀⠈⠑⠦⣀⡀⠀⠈⠉⠉⠉⠀⠀⠀⣀⡠⠔⠋⠀⠀⠀⠀⠀⠀⠀⣀⠖⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │▄▄│ 0 │⡀⠀⠀⠀⠀⠀⠉⠙⠒⠒⠒⠒⠒⠊⠉⠀⠀⠀⠀⠀⠀⠀⠀⣀⠤⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ └──┘ └────────────────────────────────────────┘ 2 ⠀0⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀real⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀1⠀
Unfortunately the color information is lost, making the colorbar on the right useless. Another interesting plotting function is isosurface, which plots a level set for a function ℝ³ → ℝ. You can think of it as a 3d contour plot with a single contour. In 2d the contours are 1 dimensional lines, in 3d they are 2 dimensional surfaces. Here is the example from the documentation, which draws a torus.
# iso surface torus(x, y, z, r = 0.2, R = 0.5) = (√(x^2 + y^2) - R)^2 + z^2 - r^2 isosurface(-1:.1:1, -1:.1:1, -1:.1:1, torus, cull = true, zoom = 2, elevation = 50) ┌────────────────────────────────────────┐ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢀⢀⠠⢄⢄⠄⠄⡠⡠⠤⡀⡀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠔⠌⠜⠀⠡⠠⠁⠡⠠⠁⠈⠄⠌⠈⠄⠌⠀⠪⠠⠤⡀⡀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⡠⠔⠅⠌⠈⠄⠌⠀⡁⡀⠨⡀⠄⠠⠡⠠⡀⠥⠠⠈⠀⠡⠠⠁⠡⠱⠢⡀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⢀⣜⠃⡁⠄⢊⠈⠄⡰⠐⡀⢂⡞⢈⡰⡨⡂⢆⡁⣱⠔⢁⠘⢀⠠⠁⡑⠠⢈⠘⣲⡀⠀⠀⠀⠀│ │⠀⠀⠀⠀⡚⠥⠁⡀⠂⢂⠈⠄⡖⡫⠗⠋⠉⠀⠀⠀⠀⠀⠈⠉⠉⠱⢝⠱⠠⠁⡐⠐⢀⠈⢌⢧⠀⠀⠀⠀│ │⠀⠀⠀⠀⡟⠤⠁⡀⠂⢂⢈⠄⢮⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡿⠠⡁⡐⠐⢀⠈⢤⢚⠀⠀⠀⠀│ │⠀⠀⠀⠀⢽⠗⠅⡀⠂⢂⢀⠂⢂⠓⡢⡄⣀⠀⠀⠀⠀⠀⢀⡀⢀⢰⠂⡑⠐⡀⡐⠐⠀⠨⢔⡟⠀⠀⠀⠀│ │⠀⠀⠀⠀⠈⠭⠄⠌⠰⠀⡀⠂⢂⠀⡐⠐⠌⠔⠑⠅⠡⠊⠢⠡⠂⢂⠀⡐⠐⣀⠐⠠⡁⡃⡑⠁⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⠈⠨⠅⠄⠌⠀⡆⢀⠐⠐⢀⠐⠐⠀⠄⠂⠂⡀⠂⡂⡀⠂⢂⠀⡂⢐⠔⠈⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠢⢥⢀⡂⡃⠇⠃⡁⡡⠨⡈⡨⠈⠬⠨⠢⢈⢠⠑⠒⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⢠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠈⠋⠓⠂⠊⠒⠂⠚⠘⠚⠙⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⣀⠼⢄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠔⠉⠀⠀⠀⠈⠑⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ └────────────────────────────────────────┘
isosurface in particular has a lot of potential for making cool stuff. The documentation also includes some information about the low-level interface the library uses for drawing, which could be used for creative purposes as well. I'm already thinking about ways to do more general 3d rendering, which would be a fun project.
I'm impressed by how well unicode plotting works out of the box in Julia. This library can easily be used to add visualizations to gemini articles, and there are definitely many more possibilities to explore.