m
m
Line 10: Line 10:
 
* <tt>m</tt> to transform a cell into markdown (text, documentation, etc.)
 
* <tt>m</tt> to transform a cell into markdown (text, documentation, etc.)
  
 +
Plotting is not native in Julia, which you might regard as a pithy, since it's such a fundamental aspect of computer programming, but this is actually a feature, as it allows us to choose the plotting environment that we like. We are not limited to built-in plotting capacities. We will be using [http://docs.juliaplots.org/ Plots]:
  
 
<pre>
 
<pre>
 
using Plots
 
using Plots
 
</pre>
 
</pre>
 +
 +
... Conway
  
 
<pre>
 
<pre>
 
heatmap(space,c=cgrad([:white, :black]), axis=nothing, legend=:none, aspect_ratio=1, yflip=true)
 
heatmap(space,c=cgrad([:white, :black]), axis=nothing, legend=:none, aspect_ratio=1, yflip=true)
 
</pre>
 
</pre>
 +
 +
cellular automata
  
 
<pre>
 
<pre>
Line 26: Line 31:
 
gif(gosper, fps=25)
 
gif(gosper, fps=25)
 
</pre>
 
</pre>
 +
 +
Plotting bitmaps is of course not the most common application we want from a computer. Maybe the most wanted overall is to plot raw data, which typically comes as a list of points or a list of pair of points (to be interpreted in the $(x, y)$ or $y_1, y_2$ sense, making one or two curves, respectively). Let us look at examples. For instance, let us track a Collatz trajectory, for which we'll redefine slightly our <tt>collatz</tt> function so that it gives us a list of the elements:
 +
 +
<pre>
 +
function collatz(n)
 +
    global lcol=[n];
 +
    while n!=1
 +
        if n%2==0
 +
            n÷=2
 +
        else
 +
            n=3n+1
 +
        end
 +
        push!(lcol, n)
 +
    end
 +
    lcol
 +
end
 +
</pre>
 +
 +
We have used <tt>push!</tt> to append the element to the list, so that we don't need to predefine arrays, given that we don't know their size ahead of time. There is also an <tt>append</tt> command which allows to append more than one element. Now we can see how the series evolves:
 +
 +
<center><wz tip="A lazy (unlabelled) plot">[[File:Screenshot_20210217_093710.png|400px]]</wz></center>
 +
 +
<pre>
 +
plot(collatz(3), lw=2, xlabel="n", ylabel="collatz series", label="3")
 +
</pre>
 +
 +
<center><wz tip="A proper version of the above.">[[File:Screenshot_20210217_094228.png|400px]]</wz></center>
 +
 +
We can use <tt>plot!</tt> to add to the previous result. Note that in Julia, ! refers to a function that alters its argument (we've seen that with <tt>push!</tt> already):
 +
 +
<pre>
 +
plot!(collatz(5), lw=2, xlabel="n", ylabel="collatz series", label="5")
 +
</pre>
 +
 +
<center><wz tip="">[[File:Screenshot_20210217_095531.png|400px]]</wz></center>
 +
 +
Like this it's easy to combine plots and computer programming:
 +
 +
<pre>
 +
p = plot()
 +
for k ∈ 2:10
 +
    global p=plot!(collatz(k), lw=2, xlabel="n", ylabel="collatz series", label=k)
 +
end
 +
p
 +
</pre>
 +
 +
<center><wz tip="">[[File:Screenshot_20210217_095649.png|400px]]</wz></center>
 +
 +
There is a lot of redundancy in this graph as various series collapse onto the same cycle. That makes for an interesting exercise for a better visualization of the Collatz series.
 +
 +
Maybe the trajectories of each series is not the most important, enlightening or interesting, baring exceptions:
 +
 +
<center><wz tip="">[[File:Screenshot_20210217_100319.png|400px]]</wz></center>
 +
 +
We would more interesting in, say, the lengths. Let's change our <tt>collatz</tt> function again:
 +
 +
<pre>
 +
function collatz(n)
 +
    global counter=1;
 +
    while n!=1
 +
        if n%2==0
 +
            n÷=2
 +
        else
 +
            n=3n+1
 +
        end
 +
        counter+=1;
 +
    end
 +
    counter
 +
end
 +
</pre>
 +
 +
In which case it is trivial to plot the lengths:
 +
 +
<pre>
 +
plot([collatz(i) for i ∈ 1:100], xlabel="n", ylabel="Length", legend=:none)
 +
</pre>
 +
 +
<center><wz tip="">[[File:Screenshot_20210217_100755.png|400px]]</wz></center>
 +
 +
This is very chaotic (that's the main feature of the sequence, it is out of control). So we'd better plot the data directly. We can keep the lines as a guide:
 +
 +
<pre>
 +
plot([collatz(i) for i ∈ 1:100], xlabel="n", ylabel="Length", legend=:none, ls=:dot);
 +
scatter!([collatz(i) for i ∈ 1:100], xlabel="n", ylabel="Length", legend=:none, color=:red)
 +
</pre>
 +
 +
This is much better than our earlier (text-based) visualization that made us very impressed with 27 (we stopped at 30!) Here we see points with a greater lengths start to become commonplace.
 +
 +
<pre>
 +
scatter([collatz(i) for i ∈ 1:10000], xlabel="n", ylabel="Length", legend=:none, markersize=.75)
 +
</pre>
 +
 +
<center><wz tip="">[[File:Screenshot_20210217_102147.png|400px]]</wz></center>
 +
 +
lengths, hist, latex, options, etc.
  
 
Plotting mathematical functions can be done as follows:
 
Plotting mathematical functions can be done as follows:
Line 33: Line 133:
 
plot!(x->x, -π, π)
 
plot!(x->x, -π, π)
 
</pre>
 
</pre>
 +
 +
2D, vector fields.
  
 
=== Links ===
 
=== Links ===

Revision as of 09:22, 17 February 2021

Crash Course in Scientific Computing

V. Plotting

We'll be using the notebook feature. The main shortcuts are:

  • toggle between edit (green) and command (blue) with esc and enter respectively.
  • a and b to insert a cell above and below the current position.
  • d d to delete the current cell
  • z to undo
  • m to transform a cell into markdown (text, documentation, etc.)

Plotting is not native in Julia, which you might regard as a pithy, since it's such a fundamental aspect of computer programming, but this is actually a feature, as it allows us to choose the plotting environment that we like. We are not limited to built-in plotting capacities. We will be using Plots:

using Plots

... Conway

heatmap(space,c=cgrad([:white, :black]), axis=nothing, legend=:none, aspect_ratio=1, yflip=true)

cellular automata

gosper = @animate for i ∈ 1:1000
           nextgen();
           heatmap(space,c=cgrad([:white, :black]), axis=nothing, legend=:none, aspect_ratio=1, yflip=true)
       end
gif(gosper, fps=25)

Plotting bitmaps is of course not the most common application we want from a computer. Maybe the most wanted overall is to plot raw data, which typically comes as a list of points or a list of pair of points (to be interpreted in the $(x, y)$ or $y_1, y_2$ sense, making one or two curves, respectively). Let us look at examples. For instance, let us track a Collatz trajectory, for which we'll redefine slightly our collatz function so that it gives us a list of the elements:

function collatz(n)
    global lcol=[n];
    while n!=1
        if n%2==0
            n÷=2
        else
            n=3n+1
        end
        push!(lcol, n)
    end
    lcol
end

We have used push! to append the element to the list, so that we don't need to predefine arrays, given that we don't know their size ahead of time. There is also an append command which allows to append more than one element. Now we can see how the series evolves:

Screenshot 20210217 093710.png
plot(collatz(3), lw=2, xlabel="n", ylabel="collatz series", label="3")
Screenshot 20210217 094228.png

We can use plot! to add to the previous result. Note that in Julia, ! refers to a function that alters its argument (we've seen that with push! already):

plot!(collatz(5), lw=2, xlabel="n", ylabel="collatz series", label="5")
Screenshot 20210217 095531.png

Like this it's easy to combine plots and computer programming:

p = plot()
for k ∈ 2:10
    global p=plot!(collatz(k), lw=2, xlabel="n", ylabel="collatz series", label=k)
end
p
Screenshot 20210217 095649.png

There is a lot of redundancy in this graph as various series collapse onto the same cycle. That makes for an interesting exercise for a better visualization of the Collatz series.

Maybe the trajectories of each series is not the most important, enlightening or interesting, baring exceptions:

Screenshot 20210217 100319.png

We would more interesting in, say, the lengths. Let's change our collatz function again:

function collatz(n)
    global counter=1;
    while n!=1
        if n%2==0
            n÷=2
        else
            n=3n+1
        end
        counter+=1;
    end
    counter
end

In which case it is trivial to plot the lengths:

plot([collatz(i) for i ∈ 1:100], xlabel="n", ylabel="Length", legend=:none)
Screenshot 20210217 100755.png

This is very chaotic (that's the main feature of the sequence, it is out of control). So we'd better plot the data directly. We can keep the lines as a guide:

plot([collatz(i) for i ∈ 1:100], xlabel="n", ylabel="Length", legend=:none, ls=:dot);
scatter!([collatz(i) for i ∈ 1:100], xlabel="n", ylabel="Length", legend=:none, color=:red)

This is much better than our earlier (text-based) visualization that made us very impressed with 27 (we stopped at 30!) Here we see points with a greater lengths start to become commonplace.

scatter([collatz(i) for i ∈ 1:10000], xlabel="n", ylabel="Length", legend=:none, markersize=.75)
Screenshot 20210217 102147.png

lengths, hist, latex, options, etc.

Plotting mathematical functions can be done as follows:

plot(sin, x, -π, π)
plot!(x->x, -π, π)

2D, vector fields.

Links