fplot Manual

\(\newcommand{\footnotename}{footnote}\) \(\def \LWRfootnote {1}\) \(\newcommand {\footnote }[2][\LWRfootnote ]{{}^{\mathrm {#1}}}\) \(\newcommand {\footnotemark }[1][\LWRfootnote ]{{}^{\mathrm {#1}}}\) \(\let \LWRorighspace \hspace \) \(\renewcommand {\hspace }{\ifstar \LWRorighspace \LWRorighspace }\) \(\newcommand {\TextOrMath }[2]{#2}\) \(\newcommand {\mathnormal }[1]{{#1}}\) \(\newcommand \ensuremath [1]{#1}\) \(\newcommand {\LWRframebox }[2][]{\fbox {#2}} \newcommand {\framebox }[1][]{\LWRframebox } \) \(\newcommand {\setlength }[2]{}\) \(\newcommand {\addtolength }[2]{}\) \(\newcommand {\setcounter }[2]{}\) \(\newcommand {\addtocounter }[2]{}\) \(\newcommand {\arabic }[1]{}\) \(\newcommand {\number }[1]{}\) \(\newcommand {\noalign }[1]{\text {#1}\notag \\}\) \(\newcommand {\cline }[1]{}\) \(\newcommand {\directlua }[1]{\text {(directlua)}}\) \(\newcommand {\luatexdirectlua }[1]{\text {(directlua)}}\) \(\newcommand {\protect }{}\) \(\def \LWRabsorbnumber #1 {}\) \(\def \LWRabsorbquotenumber "#1 {}\) \(\newcommand {\LWRabsorboption }[1][]{}\) \(\newcommand {\LWRabsorbtwooptions }[1][]{\LWRabsorboption }\) \(\def \mathchar {\ifnextchar "\LWRabsorbquotenumber \LWRabsorbnumber }\) \(\def \mathcode #1={\mathchar }\) \(\let \delcode \mathcode \) \(\let \delimiter \mathchar \) \(\def \oe {\unicode {x0153}}\) \(\def \OE {\unicode {x0152}}\) \(\def \ae {\unicode {x00E6}}\) \(\def \AE {\unicode {x00C6}}\) \(\def \aa {\unicode {x00E5}}\) \(\def \AA {\unicode {x00C5}}\) \(\def \o {\unicode {x00F8}}\) \(\def \O {\unicode {x00D8}}\) \(\def \l {\unicode {x0142}}\) \(\def \L {\unicode {x0141}}\) \(\def \ss {\unicode {x00DF}}\) \(\def \SS {\unicode {x1E9E}}\) \(\def \dag {\unicode {x2020}}\) \(\def \ddag {\unicode {x2021}}\) \(\def \P {\unicode {x00B6}}\) \(\def \copyright {\unicode {x00A9}}\) \(\def \pounds {\unicode {x00A3}}\) \(\let \LWRref \ref \) \(\renewcommand {\ref }{\ifstar \LWRref \LWRref }\) \( \newcommand {\multicolumn }[3]{#3}\) \(\require {textcomp}\) \(\newcommand {\intertext }[1]{\text {#1}\notag \\}\) \(\let \Hat \hat \) \(\let \Check \check \) \(\let \Tilde \tilde \) \(\let \Acute \acute \) \(\let \Grave \grave \) \(\let \Dot \dot \) \(\let \Ddot \ddot \) \(\let \Breve \breve \) \(\let \Bar \bar \) \(\let \Vec \vec \) \(\newcommand {\toprule }[1][]{\hline }\) \(\let \midrule \toprule \) \(\let \bottomrule \toprule \) \(\def \LWRbooktabscmidruleparen (#1)#2{}\) \(\newcommand {\LWRbooktabscmidrulenoparen }[1]{}\) \(\newcommand {\cmidrule }[1][]{\ifnextchar (\LWRbooktabscmidruleparen \LWRbooktabscmidrulenoparen }\) \(\newcommand {\morecmidrules }{}\) \(\newcommand {\specialrule }[3]{\hline }\) \(\newcommand {\addlinespace }[1][]{}\) \(\newcommand {\tcbset }[1]{}\) \(\newcommand {\tcbsetforeverylayer }[1]{}\) \(\newcommand {\tcbox }[2][]{\boxed {\text {#2}}}\) \(\newcommand {\tcboxfit }[2][]{\boxed {#2}}\) \(\newcommand {\tcblower }{}\) \(\newcommand {\tcbline }{}\) \(\newcommand {\tcbtitle }{}\) \(\newcommand {\tcbsubtitle [2][]{\mathrm {#2}}}\) \(\newcommand {\tcboxmath }[2][]{\boxed {#2}}\) \(\newcommand {\tcbhighmath }[2][]{\boxed {#2}}\)

6 Advanced Features

This page covers some of the more advanced capabilities of fplot, such as creating composite plots, adding annotations, and using raw Gnuplot commands.

NOTE: Fennel Macros are not included in this wiki page, because they have their own dedicated section.

6.1 Multiplot

fplot makes it easy to combine several plots into a single image using Gnuplot’s multiplot feature. You enable this by passing multiple plot configuration tables to the fplot.plot function. The last table argument is special: it must contain the :multiplot configuration within its :options table.

The :multiplot table accepts the following keys:

:layout: A table [rows, cols] defining the grid for the subplots.

:title: An optional overall title for the entire multiplot figure.

Example: 2x1 Multiplot

This example creates two plots stacked vertically.

Fennel

(local fplot (require :fplot))
;; --- Data ---
(local sin-data [])
(local cos-data [])
(for [i 0 100]
(let [x (* i 0.1)]
(table.insert sin-data [x (math.sin x)])
(table.insert cos-data [x (math.cos x)])))
;; --- Plotting ---
(fplot.plot
;; Plot 1: Sine
{:options {:title "Sine"}
        :datasets [{:data sin-data}]}
;; Plot 2: Cosine
{:options {:title "Cosine"}
        :datasets [{:data cos-data}]}
;; Multiplot Configuration (in the last table)
{:options {:multiplot {:layout [2 1]
                        :title "Trigonometric Functions"}}})

Lua

require("fennel").install()
local fplot = require("fplot")

-- --- Data ---
local sin_data = {}
local cos_data = {}
for i = 0, 100 do
local x = i * 0.1
table.insert(sin_data, {x, math.sin(x)})
table.insert(cos_data, {x, math.cos(x)})
end

-- --- Plotting ---
fplot.plot(
-- Plot 1: Sine
{
        options = { title = "Sine" },
        datasets = { { data = sin_data } }
},

-- Plot 2: Cosine
{
        options = { title = "Cosine" },
        datasets = { { data = cos_data } }
},

-- Multiplot Configuration (in the last table)
{
        options = {
                multiplot = {
                        layout = {2, 1},
                        title = "Trigonometric Functions"
                }
        }
}
)

(image)

Figure 1: The resulting plot generated by fplot

6.2 Labels, Arrows, and Objects

You can add arbitrary annotations to your plot using the :labels, :arrows, and :objects options.

  • :labels: Add text to the plot. Each label is a table [text, x, y, options].

  • :arrows: Draw arrows. Each arrow is a table [x1, y1, x2, y2, options].

  • :objects: Draw shapes (rectangles, circles, etc.). Each object is a table [type, definition].

Example: Annotating a Peak

Fennel

(fplot.plot
{:options {:title "Annotated Plot"
                :x-range [0 10]
                :y-range [0 12]
                :labels [["Important Peak" 5 10.5 "center"]]
                :arrows [[7 8 5.2 9.8 "head filled"]]
                :objects [["rectangle" "from 4,0 to 6,10 fs transparent solid 0.1 noborder"]]}
        :datasets [{:data [[1 2] [3 7] [5 10] [7 6] [9 3]]
                :style "linespoints"}]})

Lua

fplot.plot({
        options = {
                title = "Annotated Plot",
                ["x-range"] = {0, 10},
                ["y-range"] = {0, 12},
                labels = {
                        {"Important Peak", 5, 10.5, "center"}
                },
                arrows = {
                        {7, 8, 5.2, 9.8, "head filled"}
                },
                objects = {
                        {"rectangle", "from 4,0 to 6,10 fs transparent solid 0.1 noborder"}
                }
        },
        datasets = {
                {
                        data = {{1, 2}, {3, 7}, {5, 10}, {7, 6}, {9, 3}},
                        style = "linespoints"
                }
        }
})

(image)

Figure 2: The resulting plot generated by fplot

6.3 Custom Tics

You can take full control over the axis tic marks using the :xtics and :ytics options. This is useful for categorical data or for highlighting specific points. Provide a list of ["label", value] pairs.

Example: Labeled Tics

Fennel

(local fplot (require :fplot))

(fplot.plot
{:options {:title "Quarterly Sales"
                :xtics [["Q1" 1] ["Q2" 2] ["Q3" 3] ["Q4" 4]]
                :ytics [0 10000 20000 30000]
                :y-label "Revenue (\$)"}
        :datasets [{:data [[1 15000] [2 22000] [3 18000] [4 25000]]
                :style "boxes"
                :title "Sales"}]})

Lua

require("fennel").install()
local fplot = require("fplot")

fplot.plot({
        options = {
                title = "Quarterly Sales",
                xtics = {{"Q1", 1}, {"Q2", 2}, {"Q3", 3}, {"Q4", 4}},
                ytics = {0, 10000, 20000, 30000},
                ["y-label"] = "Revenue (\$)"
        },
        datasets = {
                {
                        data = {{1, 15000}, {2, 22000}, {3, 18000}, {4, 25000}},
                        style = "boxes",
                        title = "Sales"
                }
        }
})

(image)

Figure 3: The resulting plot generated by fplot

6.4 Extra Options (:extra-opts)

For features that are not directly exposed by fplot, you can use the :extra-opts option to pass raw command strings directly to the Gnuplot script. This provides an escape hatch for accessing the full power of Gnuplot.

Example: Setting a Custom Fill Style

Fennel

(local fplot (require :fplot))

(fplot.plot
{:options {:title "Histogram"
                :extra-opts ["set style fill solid 0.6 border -1"
                "set style histogram clustered gap 2"
                "set style data histograms"]}
        :datasets [{:title "Group A" :data [10 15 12]}
        {:title "Group B" :data [12 11 14]}]})

Lua

require("fennel").install()
local fplot = require("fplot")

fplot.plot({
        options = {
                title = "Histogram",
                ["extra-opts"] = {
                        "set style fill solid 0.6 border -1",
                        "set style histogram clustered gap 2",
                        "set style data histograms"
                }
        },
        datasets = {
                { title = "Group A", data = {10, 15, 12} },
                { title = "Group B", data = {12, 11, 14} }
        }
})

(image)

Figure 4: The resulting plot generated by fplot