123 lines
22 KiB
HTML
123 lines
22 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><title>Advanced usage · Gnuplot.jl</title><link href="https://fonts.googleapis.com/css?family=Lato|Roboto+Mono" rel="stylesheet" type="text/css"/><link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/fontawesome.min.css" rel="stylesheet" type="text/css"/><link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/solid.min.css" rel="stylesheet" type="text/css"/><link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/brands.min.css" rel="stylesheet" type="text/css"/><link href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min.css" rel="stylesheet" type="text/css"/><script>documenterBaseURL=".."</script><script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js" data-main="../assets/documenter.js"></script><script src="../siteinfo.js"></script><script src="../../versions.js"></script><link class="docs-theme-link" rel="stylesheet" type="text/css" href="../assets/themes/documenter-dark.css" data-theme-name="documenter-dark"/><link class="docs-theme-link" rel="stylesheet" type="text/css" href="../assets/themes/documenter-light.css" data-theme-name="documenter-light" data-theme-primary/><script src="../assets/themeswap.js"></script></head><body><div id="documenter"><nav class="docs-sidebar"><a class="docs-logo" href="../"><img src="../assets/logo.png" alt="Gnuplot.jl logo"/></a><div class="docs-package-name"><span class="docs-autofit">Gnuplot.jl</span></div><form class="docs-search" action="../search/"><input class="docs-search-query" id="documenter-search-query" name="q" type="text" placeholder="Search docs"/></form><ul class="docs-menu"><li><a class="tocitem" href="../">Home</a></li><li><a class="tocitem" href="../install/">Installation</a></li><li><a class="tocitem" href="../basic/">Basic usage</a></li><li class="is-active"><a class="tocitem" href>Advanced usage</a><ul class="internal"><li><a class="tocitem" href="#Named-datasets-1"><span>Named datasets</span></a></li><li><a class="tocitem" href="#Multiplot-1"><span>Multiplot</span></a></li><li><a class="tocitem" href="#Customized-layout-1"><span>Customized layout</span></a></li><li><a class="tocitem" href="#Multiple-sessions-1"><span>Multiple sessions</span></a></li><li><a class="tocitem" href="#Histograms-1"><span>Histograms</span></a></li><li><a class="tocitem" href="#Contour-lines-1"><span>Contour lines</span></a></li><li><a class="tocitem" href="#Animations-1"><span>Animations</span></a></li><li><a class="tocitem" href="#Direct-command-execution-1"><span>Direct command execution</span></a></li><li><a class="tocitem" href="#The-gnuplot-REPL-1"><span>The gnuplot REPL</span></a></li><li><a class="tocitem" href="#Dry-sessions-1"><span>Dry sessions</span></a></li></ul></li><li><a class="tocitem" href="../options/">Package options</a></li><li><a class="tocitem" href="../style/">Style guide</a></li><li><a class="tocitem" href="../terminals/">Gnuplot terminals</a></li><li><a class="tocitem" href="../recipes/">Plot recipes</a></li><li><a class="tocitem" href="../examples/">Examples</a></li><li><a class="tocitem" href="../api/">API</a></li></ul><div class="docs-version-selector field has-addons"><div class="control"><span class="docs-label button is-static is-size-7">Version</span></div><div class="docs-selector control is-expanded"><div class="select is-fullwidth is-size-7"><select id="documenter-version-selector"></select></div></div></div></nav><div class="docs-main"><header class="docs-navbar"><nav class="breadcrumb"><ul class="is-hidden-mobile"><li class="is-active"><a href>Advanced usage</a></li></ul><ul class="is-hidden-tablet"><li class="is-active"><a href>Advanced usage</a></li></ul></nav><div class="docs-right"><a class="docs-edit-link" href="https://github.com/gcalderone/Gnuplot.jl/blob/master/docs/src/advanced.md" title="Edit on GitHub"><span class="docs-icon fab"></span><span class="docs-label is-hidden-touch">Edit on GitHub</span></a><a class="docs-settings-button fas fa-cog" id="documenter-settings-button" href="#" title="Settings"></a><a class="docs-sidebar-button fa fa-bars is-hidden-desktop" id="documenter-sidebar-button" href="#"></a></div></header><article class="content" id="documenter-page"><h1 id="Advanced-usage-1"><a class="docs-heading-anchor" href="#Advanced-usage-1">Advanced usage</a><a class="docs-heading-anchor-permalink" href="#Advanced-usage-1" title="Permalink"></a></h1><p>Here we will show a few advanced techniques for data visualization using <strong>Gnuplot.jl</strong>.</p><h2 id="Named-datasets-1"><a class="docs-heading-anchor" href="#Named-datasets-1">Named datasets</a><a class="docs-heading-anchor-permalink" href="#Named-datasets-1" title="Permalink"></a></h2><p>A dataset may have an associated name whose purpose is to use it multiple times for plotting, while sending it only once to gnuplot. A dataset name must begin with a <code>$</code>.</p><p>A named dataset is defined as a <code>Pair{String, Tuple}</code>, e.g.:</p><pre><code class="language-julia">"\$name" => (1:10,)</code></pre><p>and can be used as an argument to both <code>@gp</code> and <code>gsp</code>, e.g.:</p><pre><code class="language-julia">x = range(-2pi, stop=2pi, length=100);
|
||
y = sin.(x)
|
||
name = "\$MyDataSet1"
|
||
@gp name=>(x, y) "plot $name w l lc rgb 'black'" "pl $name u 1:(1.5*\$2) w l lc rgb 'red'"</code></pre><p><img src="../assets/advanced010.png" alt/></p><p>Both curves use the same input data, but the red curve has the second column (<code>\$2</code>, corresponding to the <em>y</em> value) multiplied by a factor 1.5.</p><p>A named dataset comes in hand also when using gnuplot to fit experimental data to a model, e.g.:</p><pre><code class="language-julia"># Generate data and some noise to simulate measurements
|
||
x = range(-2pi, stop=2pi, length=20);
|
||
y = 1.5 * sin.(0.3 .+ 0.7x);
|
||
err = 0.1 * maximum(abs.(y)) .* fill(1, size(x));
|
||
y += err .* randn(length(x));
|
||
name = "\$MyDataSet1"
|
||
|
||
@gp "f(x) = a * sin(b + c*x)" :- # define an analytical model
|
||
@gp :- "a=1" "b=1" "c=1" :- # set parameter initial values
|
||
@gp :- name=>(x, y, err) :- # define a named dataset
|
||
@gp :- "fit f(x) $name via a, b, c;" # fit the data</code></pre><p>The parameter best fit values can be retrieved as follows:</p><pre><code class="language-julia">vars = gpvars();
|
||
@info("Best fit values:",
|
||
a = vars.a,
|
||
b = vars.b,
|
||
c = vars.c)</code></pre><pre><code class="language-none">┌ Info: Best fit values:
|
||
│ a = 1.51670007143536
|
||
│ b = 0.276931181635526
|
||
└ c = 0.684624514856412</code></pre><h2 id="Multiplot-1"><a class="docs-heading-anchor" href="#Multiplot-1">Multiplot</a><a class="docs-heading-anchor-permalink" href="#Multiplot-1" title="Permalink"></a></h2><p><strong>Gnuplot.jl</strong> can draw multiple plots in the same figure by exploiting the <code>multiplot</code> command. Each plot is identified by a positive integer number, which can be used as argument to <code>@gp</code> to redirect commands to the appropriate plot.</p><p>Recycling data from the previous example we can plot both data and best fit model (in plot <code>1</code>) and residuals (in plot <code>2</code>):</p><pre><code class="language-julia">@gp "f(x) = a * sin(b + c*x)"
|
||
@gp :- "a=$(vars.a)" "b=$(vars.b)" "c=$(vars.c)"
|
||
@gp :- name=>(x, y, err)
|
||
@gp :- "set multiplot layout 2,1"
|
||
@gp :- 1 "p $name w errorbars t 'Data'"
|
||
@gp :- "p $name u 1:(f(\$1)) w l t 'Best fit model'"
|
||
@gp :- 2 "p $name u 1:((f(\$1)-\$2) / \$3):(1) w errorbars t 'Resid. [{/Symbol s}]'"
|
||
@gp :- [extrema(x)...] [0,0] "w l notit dt 2 lc rgb 'black'" # reference line</code></pre><p><img src="../assets/advanced011.png" alt/></p><p>Note that the order of the plots is not relevant, i.e. we would get the same results with:</p><pre><code class="language-julia">@gp "f(x) = a * sin(b + c*x)"
|
||
@gp :- "a=$(vars.a)" "b=$(vars.b)" "c=$(vars.c)"
|
||
@gp :- name=>(x, y, err)
|
||
@gp :- "set multiplot layout 2,1"
|
||
@gp :- 2 "p $name u 1:((f(\$1)-\$2) / \$3):(1) w errorbars t 'Resid. [{/Symbol s}]'"
|
||
@gp :- [extrema(x)...] [0,0] "w l notit dt 2 lc rgb 'black'" # reference line
|
||
@gp :- 1 "p $name w errorbars t 'Data'"
|
||
@gp :- "p $name u 1:(f(\$1)) w l t 'Best fit model'"</code></pre><h2 id="Customized-layout-1"><a class="docs-heading-anchor" href="#Customized-layout-1">Customized layout</a><a class="docs-heading-anchor-permalink" href="#Customized-layout-1" title="Permalink"></a></h2><p>It is also possible to customize the plot layout using the margin keywords (see <a href="#Histograms-1">Histograms</a> for further info on how to generate andi display histograms):</p><pre><code class="language-julia"># Generate random numbers
|
||
x = randn(1000);
|
||
y = randn(1000);
|
||
|
||
# Overall plot margins (normalized in the range 0:1)
|
||
margins = (l=0.08, r=0.98, b=0.13, t=0.98)
|
||
|
||
# Right and top margins of main plot
|
||
right, top = 0.8, 0.75
|
||
|
||
# Gap between main plot and histograms
|
||
gap = 0.015
|
||
|
||
# Main plot
|
||
@gp "set multiplot"
|
||
@gp :- 1 ma=margins rma=right tma=top :-
|
||
@gp :- x y "w p notit" xlab="X" ylab="Y"
|
||
xr = gpranges().x # save current X range
|
||
yr = gpranges().y # save current Y range
|
||
|
||
# Histogram on X
|
||
h = hist(x, nbins=10)
|
||
@gp :- 2 ma=margins bma=top+gap rma=right :-
|
||
@gp :- "set xtics format ''" "set ytics format ''" xlab="" ylab="" :-
|
||
bs = fill(h.binsize, length(h.bins));
|
||
@gp :- xr=xr h.bins h.counts./2 bs./2 h.counts./2 "w boxxy notit fs solid 0.4" :-
|
||
|
||
# Histogram on Y
|
||
h = hist(y, nbins=10)
|
||
@gp :- 3 ma=margins lma=right+gap tma=top :-
|
||
@gp :- "unset xrange" :-
|
||
bs = fill(h.binsize, length(h.bins));
|
||
@gp :- yr=yr h.counts./2 h.bins h.counts./2 bs./2 "w boxxy notit fs solid 0.4" :-
|
||
@gp</code></pre><p><img src="../assets/advanced011b.png" alt/></p><h3 id="Mixing-2D-and-3D-plots-1"><a class="docs-heading-anchor" href="#Mixing-2D-and-3D-plots-1">Mixing 2D and 3D plots</a><a class="docs-heading-anchor-permalink" href="#Mixing-2D-and-3D-plots-1" title="Permalink"></a></h3><p>A multiplot can also mix 2D and 3D plots:</p><pre><code class="language-julia">x = y = -10:0.33:10
|
||
@gp "set multiplot layout 1,2"
|
||
|
||
# 2D
|
||
@gp :- 1 x sin.(x) ./ x "w l notit"
|
||
|
||
# 3D
|
||
sinc2d(x,y) = sin.(sqrt.(x.^2 + y.^2))./sqrt.(x.^2+y.^2)
|
||
fxy = [sinc2d(x,y) for x in x, y in y]
|
||
@gsp :- 2 x y fxy "w pm3d notit"</code></pre><p><img src="../assets/advanced012.png" alt/></p><h2 id="Multiple-sessions-1"><a class="docs-heading-anchor" href="#Multiple-sessions-1">Multiple sessions</a><a class="docs-heading-anchor-permalink" href="#Multiple-sessions-1" title="Permalink"></a></h2><p><strong>Gnuplot.jl</strong> can handle multiple sessions, i.e. multiple gnuplot processes running simultaneously. Each session is identified by an ID (<code>sid::Symbol</code>, in the documentation).</p><p>In order to redirect commands to a specific session simply insert a symbol into your <code>@gp</code> or <code>@gsp</code> call, e.g.:</p><pre><code class="language-julia">@gp :GP1 "plot sin(x)" # opens first window
|
||
@gp :GP2 "plot sin(x)" # opens secondo window
|
||
@gp :- :GP1 "plot cos(x)" # add a plot on first window</code></pre><p>The session ID can appear in every position in the argument list, but only one ID can be present in each call. If the session ID is not specified the <code>:default</code> session is used.</p><p>The names of all current sessions can be retrieved with <a href="../api/#Gnuplot.session_names"><code>session_names()</code></a>:</p><pre><code class="language-julia-repl">julia> println(session_names())
|
||
[:default, :GP1, :GP2]</code></pre><p>To quit a specific session use <a href="../api/#Gnuplot.quit"><code>Gnuplot.quit()</code></a>:</p><pre><code class="language-julia-repl">julia> Gnuplot.quit(:GP1)
|
||
0</code></pre><p>The output value is the exit status of the underlying gnuplot process.</p><p>You may also quit all active sessions at once with <a href="../api/#Gnuplot.quitall"><code>Gnuplot.quitall()</code></a>:</p><pre><code class="language-julia-repl">julia> Gnuplot.quitall()</code></pre><h2 id="Histograms-1"><a class="docs-heading-anchor" href="#Histograms-1">Histograms</a><a class="docs-heading-anchor-permalink" href="#Histograms-1" title="Permalink"></a></h2><p><strong>Gnuplot.jl</strong> provides facilities to compute and display histograms, e.g.:</p><pre><code class="language-julia">x = randn(1000);
|
||
@gp hist(x)</code></pre><p><img src="../assets/advanced013a.png" alt/></p><p>The <a href="../api/#Gnuplot.hist"><code>hist()</code></a> function also accept keywords to set the range to consider (<code>range=</code> keyword) and either the bin size (<code>bs=</code>) or the total number of bins (<code>nbins=</code>) in the histogram. A finer control on the output is achieved by exploiting the fields of the returned (<a href="../api/#Gnuplot.Histogram1D"><code>Gnuplot.Histogram1D</code></a>) structure, e.g.:</p><pre><code class="language-julia">x = randn(1000);
|
||
h = hist(x, range=3 .* [-1,1], bs=0.5)
|
||
@gp h.bins h.counts "w histep t 'Data' lc rgb 'red'"</code></pre><p><img src="../assets/advanced013b.png" alt/></p><p>The <a href="../api/#Gnuplot.hist"><code>hist()</code></a> function compute also 2D histograms by passing two vectors (with the same lengths), e.g.: </p><pre><code class="language-julia">x = randn(10_000)
|
||
y = randn(10_000)
|
||
h = hist(x, y)
|
||
@gp h</code></pre><p><img src="../assets/advanced014a.png" alt/></p><p>Again, a finer control can be achieved by specifying ranges, bin size or number of bins (along both dimensions) and by explicitly using the content of the returned <a href="../api/#Gnuplot.Histogram2D"><code>Gnuplot.Histogram2D</code></a> structure:</p><pre><code class="language-julia">x = randn(10_000)
|
||
y = randn(10_000)
|
||
h = hist(x, y, bs1=0.25, nbins2=20, range1=[-3,3], range2=[-3,3])
|
||
@gp "set size ratio -1" h.bins1 h.bins2 h.counts "w image notit"</code></pre><p><img src="../assets/advanced014b.png" alt/></p><p>Alternatively, 2D histograms may be displayed using the <code>boxxyerror</code> plot style which allows more flexibility in, e.g., handling transparencies and drawing the histogram grid. In this case the data can be prepared using the <a href="../api/#Gnuplot.boxxy"><code>boxxy()</code></a> function, as follows:</p><pre><code class="language-julia">@gp "set size ratio -1" "set style fill solid 0.5 border lc rgb 'gray'" :-
|
||
@gp :- boxxy(h) "w boxxy notit lc pal"</code></pre><p><img src="../assets/advanced014c.png" alt/></p><h2 id="Contour-lines-1"><a class="docs-heading-anchor" href="#Contour-lines-1">Contour lines</a><a class="docs-heading-anchor-permalink" href="#Contour-lines-1" title="Permalink"></a></h2><p>Although gnuplot already handles contours by itself (with the <code>set contour</code> command), <strong>Gnuplot.jl</strong> provides a way to calculate contour lines paths before displaying them, using the <a href="../api/#Gnuplot.contourlines"><code>contourlines()</code></a> function. We may preview such lines with:</p><pre><code class="language-julia">x = randn(10_000)
|
||
y = randn(10_000)
|
||
h = hist(x, y)
|
||
clines = contourlines(h, "levels discrete 10, 30, 60, 90");
|
||
@gp clines</code></pre><p><img src="../assets/advanced014d.png" alt/></p><p>By exploiting the fields of the <a href="../api/#Gnuplot.IsoContourLines"><code>Gnuplot.IsoContourLines</code></a> structure we may also customize line widths, colors and dashed pattern according to their z level, and plot them on top of the 2D histogram:</p><pre><code class="language-julia">@gp "set size ratio -1" "set style fill solid 0.5 border lc rgb 'gray'" :-
|
||
@gp :- boxxy(h) "w boxxy notit lc pal"
|
||
for i in 1:length(clines)
|
||
@gp :- clines[i].data "w l t '$(clines[i].z)' lw $i dt $i lc pal" :-
|
||
end
|
||
@gp :- key="outside top center box horizontal"</code></pre><p><img src="../assets/advanced014e.png" alt/></p><p>The <a href="../api/#Gnuplot.contourlines"><code>contourlines()</code></a> function also allows to calculate the contour lines encompassing a given fraction of the total counts of a 2D histogram. E.g. to plot the contours corresponding to 1, 2, and 3 <span>$\sigma$</span> of a 2D Gaussian distribution:</p><pre><code class="language-julia">x = randn(10^5);
|
||
y = randn(10^5);
|
||
h = hist(x, y, nbins1=20, nbins2=20);
|
||
|
||
# Calculate probability within 0 < r < σ
|
||
p(σ) = round(1 - exp(-(σ^2) / 2), sigdigits=3)
|
||
|
||
# Draw contour lines at 1, 2 and 3 σ
|
||
clines = contourlines(h, p.(1:3));
|
||
@gp palette(:beach, smooth=true, rev=true) "set grid front" "set size ratio -1" h clines</code></pre><p><img src="../assets/advanced014f.png" alt/></p><h2 id="Animations-1"><a class="docs-heading-anchor" href="#Animations-1">Animations</a><a class="docs-heading-anchor-permalink" href="#Animations-1" title="Permalink"></a></h2><p>The <a href="#Multiplot-1">Multiplot</a> capabilities can also be used to stack plots one above the other in order to create an animation, as in the following example:</p><pre><code class="language-julia">x = y = -10:0.33:10
|
||
fz(x,y) = sin.(sqrt.(x.^2 + y.^2))./sqrt.(x.^2+y.^2)
|
||
fxy = [fz(x,y) for x in x, y in y]
|
||
@gsp "set xyplane at 0" "unset colorbox" cbr=[-1,1] zr=[-1,1]
|
||
frame = 0
|
||
for direction in [-1,1]
|
||
for factor in -1:0.1:1
|
||
global frame += 1
|
||
@gsp :- frame x y direction * factor .* fxy "w pm3d notit" :-
|
||
end
|
||
end
|
||
@gsp</code></pre><p>Here the <code>frame</code> variable is used as multiplot index. The animation can be saved in a GIF file with:</p><pre><code class="language-julia">save(term="gif animate size 480,360 delay 5", output="assets/animation.gif")</code></pre><p><img src="../assets/animation.gif" alt/></p><h2 id="Direct-command-execution-1"><a class="docs-heading-anchor" href="#Direct-command-execution-1">Direct command execution</a><a class="docs-heading-anchor-permalink" href="#Direct-command-execution-1" title="Permalink"></a></h2><p>When gnuplot commands are passed to <code>@gp</code> or <code>@gsp</code> they are stored in a session for future use, or to be saved in <a href="../basic/#Gnuplot-scripts-1">Gnuplot scripts</a>. If you simply wish to execute a command without storing it in the session, and possibly retrieve a value, use <a href="../api/#Gnuplot.gpexec"><code>gpexec</code></a>. E.g., to retrieve the value of a gnuplot variable:</p><pre><code class="language-julia-repl">julia> gpexec("print GPVAL_TERM")
|
||
"unknown"</code></pre><p>You may also provide a session ID as first argument (see <a href="#Multiple-sessions-1">Multiple sessions</a>) to redirect the command to a specific session.</p><p>Alternatively you may start the <a href="#The-gnuplot-REPL-1">The gnuplot REPL</a> to type commands directly from the Julia prompt.</p><h2 id="The-gnuplot-REPL-1"><a class="docs-heading-anchor" href="#The-gnuplot-REPL-1">The gnuplot REPL</a><a class="docs-heading-anchor-permalink" href="#The-gnuplot-REPL-1" title="Permalink"></a></h2><p>The <strong>Gnuplot.jl</strong> package comes with a built-in REPL mode to directly send commands to the underlying gnuplot process. Since the REPL is a global resource, the gnuplot mode is not enabled by default. You can start it with:</p><pre><code class="language-julia">Gnuplot.repl_init(start_key='>')</code></pre><p>The customizable <code>start_key</code> character is the key which triggers activation of the REPL mode. To quit the gnuplot REPL mode hit the <code>backspace</code> key.</p><h2 id="Dry-sessions-1"><a class="docs-heading-anchor" href="#Dry-sessions-1">Dry sessions</a><a class="docs-heading-anchor-permalink" href="#Dry-sessions-1" title="Permalink"></a></h2><p>A "<em>dry session</em>" is a session with no underlying gnuplot process. To enable dry sessions type:</p><pre><code class="language-julia">Gnuplot.options.dry = true;</code></pre><p>before starting a session (see also <a href="../options/#Options-1">Options</a>). Note that the <code>dry</code> option is a global one, i.e. it affects all sessions started after setting the option.</p><p>Clearly, no plot can be generated in dry sessions. Still, they are useful to run <strong>Gnuplot.jl</strong> code without raising errors (no attempt will be made to communicate with the underlying process). Moreover, <a href="../basic/#Gnuplot-scripts-1">Gnuplot scripts</a> can also be generated in a dry session, without the additional overhead of sending data to the gnuplot process.</p><p>If a gnuplot process can not be started the package will print a warning, and automatically enable dry sessions.</p></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../basic/">« Basic usage</a><a class="docs-footer-nextpage" href="../options/">Package options »</a></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> on <span class="colophon-date" title="Tuesday 28 April 2020 19:19">Tuesday 28 April 2020</span>. Using Julia version 1.4.0.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|