|
| 1 | +"A quick script to for plotting a list of floats. |
| 2 | +
|
| 3 | +Takes a list of floats and a real function, plots both on a graph in both |
| 4 | +linear and log scale. Requires [Makie] (specifically CairoMakie) for plotting. |
| 5 | +
|
| 6 | +[Makie]: https://docs.makie.org/stable/ |
| 7 | +" |
| 8 | + |
| 9 | +using CairoMakie |
| 10 | + |
| 11 | +CairoMakie.activate!(px_per_unit=10) |
| 12 | + |
| 13 | +"Apply a function, returning the default if there is a domain error" |
| 14 | +function map_or_default( |
| 15 | + input::AbstractFloat, |
| 16 | + f::Function, |
| 17 | + default::AbstractFloat |
| 18 | +)::AbstractFloat |
| 19 | + try |
| 20 | + return f(input) |
| 21 | + catch |
| 22 | + return default |
| 23 | + end |
| 24 | +end |
| 25 | + |
| 26 | +"Read inputs from a file, create both linear and log plots" |
| 27 | +function plot_one( |
| 28 | + fig::Figure, |
| 29 | + base_name::String, |
| 30 | + fn_name::String, |
| 31 | + f::Function; |
| 32 | + xlims::Union{Tuple{Any,Any},Nothing}, |
| 33 | + xlims_log::Union{Tuple{Any,Any},Nothing}, |
| 34 | +)::Nothing |
| 35 | + float_file = "$base_name.txt" |
| 36 | + lin_out_file = "$base_name.png" |
| 37 | + log_out_file = "$base_name-log.png" |
| 38 | + |
| 39 | + if xlims === nothing |
| 40 | + xlims = (-6, 6) |
| 41 | + end |
| 42 | + if xlims_log === nothing |
| 43 | + xlims_log = (xlims[1] * 500, xlims[2] * 500) |
| 44 | + end |
| 45 | + |
| 46 | + inputs = readlines(float_file) |
| 47 | + |
| 48 | + # Parse floats |
| 49 | + x = map((v) -> parse(Float32, v), inputs) |
| 50 | + # Apply function to the test points |
| 51 | + y = map((v) -> map_or_default(v, f, 0.0), x) |
| 52 | + |
| 53 | + # Plot the scatter plot of our checked values as well as the continuous function |
| 54 | + ax = Axis(fig[1, 1], limits=(xlims, nothing), title=fn_name) |
| 55 | + lines!(ax, xlims[1] .. xlims[2], f, color=(:blue, 0.4)) |
| 56 | + scatter!(ax, x, y, color=(:green, 0.3)) |
| 57 | + save(lin_out_file, fig) |
| 58 | + delete!(ax) |
| 59 | + |
| 60 | + # Same as above on a log scale |
| 61 | + ax = Axis( |
| 62 | + fig[1, 1], |
| 63 | + limits=(xlims_log, nothing), |
| 64 | + xscale=Makie.pseudolog10, |
| 65 | + title="$fn_name (log scale)" |
| 66 | + ) |
| 67 | + lines!(ax, xlims_log[1] .. xlims_log[2], f, color=(:blue, 0.4)) |
| 68 | + scatter!(ax, x, y, color=(:green, 0.3)) |
| 69 | + save(log_out_file, fig) |
| 70 | + delete!(ax) |
| 71 | +end |
| 72 | + |
| 73 | +# Args alternate `name1 path1 name2 path2` |
| 74 | +fn_names = ARGS[1:2:end] |
| 75 | +base_names = ARGS[2:2:end] |
| 76 | + |
| 77 | +for idx in eachindex(fn_names) |
| 78 | + fn_name = fn_names[idx] |
| 79 | + base_name = base_names[idx] |
| 80 | + |
| 81 | + xlims = nothing |
| 82 | + xlims_log = nothing |
| 83 | + |
| 84 | + fig = Figure() |
| 85 | + |
| 86 | + # Map string function names to callable functions |
| 87 | + if fn_name == "cos" |
| 88 | + f = cos |
| 89 | + xlims_log = (-pi * 10, pi * 10) |
| 90 | + elseif fn_name == "cbrt" |
| 91 | + f = cbrt |
| 92 | + xlims = (-2.0, 2.0) |
| 93 | + elseif fn_name == "sqrt" |
| 94 | + f = sqrt |
| 95 | + xlims = (-1.1, 6.0) |
| 96 | + xlims_log = (-1.1, 5000.0) |
| 97 | + else |
| 98 | + println("unrecognized function name `$fn_name`; update plot_file.jl") |
| 99 | + end |
| 100 | + |
| 101 | + println("plotting $fn_name") |
| 102 | + plot_one( |
| 103 | + fig, |
| 104 | + base_name, |
| 105 | + fn_name, |
| 106 | + f, |
| 107 | + xlims=xlims, |
| 108 | + xlims_log=xlims_log, |
| 109 | + ) |
| 110 | +end |
| 111 | + |
| 112 | +base_name = ARGS[1] |
| 113 | +fn_name = ARGS[2] |
0 commit comments