Introducing Julia/Plotting

« Introducing Julia
Plotting
»
Working with dates and times Metaprogramming

PlottingEdit

There are a number of different packages for plotting in Julia, and there's probably one to suit your needs and tastes. This section is a quick introduction to one of them, Plots.jl, which is interesting because it talks to many of the other plotting packages. Before making plots with Julia, download and install the first plotting package or any or all to choose from (to get the prompt press ]):

(v1.0) pkg> add Plots PyPlot GR UnicodePlots  # See also Gnuplot.jl (and Gaston.jl alternative for)

The first package, Plots, is a high-level plotting package that interfaces with other plotting packages, which here are referred to as 'back-ends'. They act as the graphics "engines" that produce the graphics. Each of these is also a stand-alone plotting package, and can be used separately, but the advantage of using Plots as the interface is, as you'll see, a simpler and consistent interface.

See also the powerful Makie.jl, which is unrelated to Plots.jl, and has its own backends, such as GLMakie.jl, and many extensions such as AlgebraOfGraphics.jl (these are not explained more in the article, except for this installation example):

(v1.6) pkg> add GLMakie AlgebraOfGraphics

You can start using the Plots.jl package in a Julia session in the usual way:

julia> using Plots

You usually want to plot one or more series, arrays of numerical values. Alternatively, you can provide one or more functions to generate numerical values.

In this example, we'll plot the phases (illuminated fractions) of the moon for the month of May, 2022.

julia> using AstroLib  # add if necessary with ] add AstroLib
julia> using Dates 
julia> points = DateTime(2022,05,01):Dates.Hour(1):DateTime(2022,05,31,23,59,59)
julia> moonphases = mphase.(jdcnv.(points)) 

We now have an array of Float64 values, one for each hour of the month, representing how much of the moon's disk is illuminated:

julia> moonphases
744-element Vector{Float64}:
 0.0002806471321559201
 0.00041259024384365794
 0.0005791256946680035
 0.0007801698949687075
 0.0010156372084771381
 0.0012854399754271273
 ⋮
 0.015263669925646928
 0.016249662554591593
 0.017266056993952783
 0.018312770267986556
 0.019389718259650524
 0.020496815690093984

To plot these series, just pass them to Plots' plot() function.

julia> plot(points, moonphases)

This has used the first available plotting engine (GR.jl). Plots has added other plotting "furniture" and then plotted everything for you.

 

If you want to switch to a different engine, use one of the provided functions: gr(), unicodeplots(), plotly(), and so on. For example, to switch to using the Unicodeplots plotting package (which uses Unicode characters to make plots, and is ideal for use in the REPL/terminal), do this:

julia> unicodeplots()

julia> plot(moonphases)
   
    ┌────────────────────────────────────────┐ 
  1 │                .::.                 │ 
    │               .:     '.                │ 
    │              :'       ':               │ 
    │             :'         '.              │ 
    │            .'           :.             │ 
    │           .:             :             │ 
    │          .:               :            │ 
    │         .:                ':           │ 
    │         :                  :.          │ 
    │        :                    :.         │ 
    │       :'                     :.        │ 
    │      :'                       :.       │ 
    │    .:                          :.      │ 
    │   .:                            :.     │ 
  0 │..:'                              ':....│ 
    └────────────────────────────────────────┘

Customizing plotsEdit

There is copious documentation for the Plots.jl package, and after studying it you'll be able to spend hours tweaking and customizing your plots to your heart's content. Here's just one example of a plot of the equation of time for every day in a year.

The ticks along the x-axis are the numbers from 1:365. It would be better to see the dates themselves. First, create the strings:

julia> days = Dates.DateTime(2018, 1, 1, 0, 0, 0):Dates.Day(1):Dates.DateTime(2018, 12, 31, 0, 0, 0)
julia> datestrings = Dates.format.(days, "u dd")

The supplied value for the xticks option is a tuple consisting of two arrays/ranges:

(xticks = (1:14:366, datestrings[1:14:366])

the first provides the numerical values, the second provides matching text labels for the ticks.

Extra labels and legends are easily added. You can access colors from the Colors.jl package:

julia>  plot!(                                    
    eq_values,                                        
                                                      
    label  = "equation of time (calculated)",     
    line=(:black, 0.5, 6, :solid),                
                                                  
    size=(800, 600),                              
                                                  
    xticks = (1:14:366, datestrings[1:14:366]),   
    yticks = -20:2.5:20,                          
                                                  
    ylabel = "Minutes faster or slower than GMT", 
    xlabel = "day in year",                       
                                                  
    title  = "The Equation of Time",              
    xrotation = rad2deg(pi/3),                    
                                                  
    fillrange = 0,                                
    fillalpha = 0.25,                             
    fillcolor = :lightgoldenrod,                  
                                                  
    background_color = :ivory                     
    )                                             

 

Other packagesEdit

UnicodePlotsEdit

If you work in the REPL a lot, perhaps you want a quick and easy way to draw plots that use text rather than graphics for output? The UnicodePlots.jl package uses Unicode characters to draw various plots, avoiding the need to load various graphic libraries. It can produce:

  • scatter plots
  • line plots
  • bar plots (horizontal)
  • staircase plots
  • histograms (horizontal)
  • sparsity patterns
  • density plots

Download and add it to your Julia installation, if you haven't already done so:

pkg> add UnicodePlots

You have to do this just once. Now you load the module and import the functions:

julia> using UnicodePlots

Here is a quick example of a line plot:

julia> myPlot = lineplot([1, 2, 3, 7], [1, 2, -5, 7], title="My Plot", border=:dotted)
                       My Plot
      ⡤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⢤
   10 ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
      ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
      ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
      ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
      ⡇⠀⠀⠀⠀⠔⠒⠊⠉⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠔⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
      ⡇⠉⠉⠉⠉⠉⠉⠉⠉⠉⠫⡉⠉⠉⠉⠉⠉⢉⠝⠋⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠁⢸
      ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠱⡀⠀⢀⡠⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
      ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⠔⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
      ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
  -10 ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
      ⠓⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠚
      0                                       10

And here's a density plot:

julia> myPlot = densityplot(collect(1:100), randn(100), border=:dotted)
      ⡤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⢤
   10 ⡇                                        ⢸
      ⡇                                        ⢸
      ⡇                                        ⢸
      ⡇                                        ⢸
      ⡇                                        ⢸
      ⡇                                        ⢸
      ⡇                                        ⢸
      ⡇                            ░           ⢸
      ⡇ ░░░        ░ ▒░  ▒░     ░  ░ ░ ░ ░   ░ ⢸
      ⡇░░  ░▒░░▓▒▒ ▒░░ ▓░░ ░░░▒░ ░ ░   ▒ ░ ░▒░░⢸
      ⡇▓▒█▓▓▒█▓▒▒▒█▒▓▒▓▒▓▒▓▓▒▓▒▓▓▓█▒▒█▓▒▓▓▓▓▒▒▒⢸
      ⡇    ░     ░         ░░░ ░    ▒ ░ ░ ░░ ░ ⢸
      ⡇                          ░             ⢸
      ⡇                                        ⢸
      ⡇                                        ⢸
      ⡇                                        ⢸
      ⡇                                        ⢸
      ⡇                                        ⢸
      ⡇                                        ⢸
  -10 ⡇                                        ⢸
      ⠓⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠚
      0                                      100

(Note that it needs the terminal environment for the displayed graphs to be 100% successful - when you copy and paste, some of the magic is lost.)

VegaLiteEdit

allows you to create visualizations in a web browser window. VegaLite is a visualization grammar, a declarative format for creating and saving visualization designs. With VegaLite you can describe data visualizations in a JSON format, and generate interactive views using either HTML5 Canvas or SVG. You can produce:

  • Area plots
  • Bar plots/Histograms
  • Line plots
  • Scatter plots
  • Pie/Donut charts
  • Waterfall charts
  • Wordclouds

To use VegaLite, first add the package to your Julia installation. You have to do this just once:

pkg> add VegaLite

Here's how to create a stacked area plot.

julia> using VegaLite
julia> x = [0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9]
julia> y = [28, 43, 81, 19, 52, 24, 87, 17, 68, 49, 55, 91, 53, 87, 48, 49, 66, 27, 16, 15]
julia> g = [0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1]
 
julia> a = areaplot(x = x, y = y, group = g, stacked = true)

 

A general feature of VegaLite is that you can modify a visualization after you've created it. So, let's change the color scheme using a function (notice the "!" to indicate that the arguments are modified):

julia> colorscheme!(a, ("Reds", 3))

 

You can create pie (and donut) charts easily by supplying two arrays. The x array provides the labels, the y array provides the quantities:

julia> fruit = ["peaches", "plums", "blueberries", "strawberries", "bananas"];
julia> bushels = [100, 32, 180, 46, 21];
julia> piechart(x = fruit, y = bushels, holesize = 125)