2 Key forms

Graphite has a number of important forms that are effectively required for anything to come out of it.

First off, in order to plot data, we need to read data in. To do this, Graphite uses the data-frame library. Usually, to read in data from a CSV, you use df-read/csv. Various other formats are supported by data-frame, which you can find by consulting its documentation.

The main form of Graphite-generated plots is the function graph. It takes two mandatory keywords, #:data and #:mapping, which correspond to (respectively) the data-frame? to read your data from and the aes? to retrieve global aesthetics from (more on that later). Finally, it takes any amount of renderers, such as points and lines, as positional arguments. As an example, a usual call to graph would look like:
(graph #:data some-data
       #:mapping (aes #:some-key some-value)
       #:title "a title"
       (renderer-1)
       (renderer-2))

Aesthetic mappings, created with the aes form, creates a set of key-value mappings, with keys specified by keywords. Each key represents an "aesthetic" to map a variable to, and each value represents a variable in the data to map it to. If a value is not present and not mandatory, it is read as #f. These can correspond to positional aesthetics (the x-axis with #:x, and the y-axis with #:y), colorings (such as #:discrete-color to points), or another required variable (such as #:perc-error to error-bars). The most important thing is that aesthetic mappings only correspond to mapping an aesthetic to a variable: if you want to set some visual element of the plot without respect to some variable, you likely want a keyword argument passed directly to one of your renderers.

graph takes a global aesthetic mapping, and each renderer takes its own aesthetic mapping as well, all with the #:mapping keyword. When a renderer is called, it inherits aesthetics from both the global mapping passed to graph and the local mapping passed to it. In addition, the local mapping overrides the global mapping’s settings. So, for example, in this code:
(graph #:data some-data
       #:mapping (aes #:foo "bar" #:baz "quux")
       (renderer-1 #:mapping (aes #:baz "waldo" #:fruit "apple")))
the aesthetic mapping that is actually used in renderer-1 would be (aes #:foo "bar" #:baz "waldo" #:fruit "apple"), inheriting #:foo from the global mapping and overriding #:baz.