Essaywriter

Chart guide

Code on the page

Type ``` and Enter for a block of Ruby; Enter three times at its end to leave it. Blocks run top to bottom and share what they define, so data in one block can be charted in the next. A chart shows under its block a moment after you stop typing.

A first chart

Data, then a chart of it. Keywords say what goes where.

visits = dataset month: [ 1, 2, 3, 4, 5, 6 ], patients: [ 42, 51, 48, 63, 70, 74 ]

chart :line, visits, x: :month, y: :patients, title: "Patients seen"

Settings in a block

The same settings, one per line. Keywords and a block can be mixed.

visits = dataset month: [ 1, 2, 3, 4, 5, 6 ], patients: [ 42, 51, 48, 63, 70, 74 ]

chart :line, visits do
  title "Patients seen"
  x :month, label: "Month"
  y :patients, label: "Patients", from: 0
  color :red
  hline 60, label: "Capacity"
  caption "Patients seen in clinic each month."
end

Data

Typed as CSV

Headers become column names: “Systolic BP” is :systolic_bp, and keeps its heading on axes.

bp = dataset <<~CSV
  Age,Systolic BP,Arm
  34,120,drug
  51,135,placebo
  62,141,drug
CSV

Columns, or rows

A list per column, or a hash per row.

bp = dataset age: [ 34, 51, 62 ], systolic: [ 120, 135, 141 ]
bp = dataset [ { age: 34, systolic: 120 }, { age: 51, systolic: 135 } ]

Choosing and shaping

Every verb gives a new dataset; the old one stays as it was.

trials = dataset week: [ 0, 4, 8, 0, 4, 8 ], arm: %w[ drug drug drug placebo placebo placebo ],
  response: [ 0.1, 0.4, 0.6, 0.1, 0.2, 0.25 ]

drug = trials.where(arm: "drug")
later = trials.where { week >= 4 }
means = trials.summarize(by: :arm) { |rows| { mean: rows.mean(:response) } }
percent = trials.derive(:percent) { response * 100 }
puts means.to_a.inspect

Or drop a CSV, TSV or JSON file on the page: it's kept under Data, and a line reading it goes in, like trials = import "trials". A web address works too: import "https://…/cases.csv".

More verbs: sort_by, order, first, count_by, only, except, rename, relabel, join, longer, group_by, and mean, median, sd, quantile, sum, min, max of a column.

Kinds of chart

Line

Change over time. A coloured column makes a line per group, named at its end.

trials = dataset week: [ 0, 4, 8, 12, 0, 4, 8, 12 ], arm: %w[ drug drug drug drug placebo placebo placebo placebo ],
  response: [ 0.1, 0.35, 0.5, 0.6, 0.1, 0.15, 0.2, 0.22 ]

chart :line, trials, x: :week, y: :response, color: :arm, y_format: :percent

Scatter

Two measures against each other; trend adds a least-squares line and R².

patients = dataset bmi: [ 21, 24, 27, 29, 31, 34, 36 ], sbp: [ 118, 121, 128, 131, 137, 142, 149 ]

chart :scatter, patients, x: :bmi, y: :sbp, trend: true

Bar

Amounts by category. stack, horizontal and labels change how they sit.

arms = dataset arm: %w[ Placebo Low High ], responders: [ 0.21, 0.38, 0.52 ]

chart :bar, arms, x: :arm, y: :responders, labels: true, y_format: :percent

Area

Totals over time; stacked, the parts of a whole.

beds = dataset week: [ 1, 2, 3, 1, 2, 3 ], ward: %w[ ICU ICU ICU General General General ], patients: [ 8, 12, 9, 30, 41, 37 ]

chart :area, beds, x: :week, y: :patients, color: :ward, stack: true

Step

Values that hold until they change, like doses.

dose = dataset day: [ 0, 3, 7, 14 ], mg: [ 5, 10, 20, 20 ]

chart :step, dose, x: :day, y: :mg

Histogram

How one measure is spread. bins sets how many bars.

ages = dataset age: [ 23, 31, 34, 38, 41, 44, 45, 47, 52, 53, 56, 58, 61, 64, 67, 71, 78 ]

chart :histogram, ages, x: :age, bins: 6

Box

Median, quartiles and outliers by group. points shows every value too.

levels = dataset arm: %w[ A A A A A B B B B B ], crp: [ 3, 5, 6, 8, 21, 2, 3, 3, 4, 6 ]

chart :box, levels, x: :arm, y: :crp, points: true

Forest

Estimates with intervals, one row each. “Overall” rows are drawn as diamonds.

studies = dataset [
  { study: "Smith 2019", ratio: 0.82, low: 0.61, high: 1.10, n: 120 },
  { study: "Lee 2021", ratio: 0.66, low: 0.51, high: 0.86, n: 300 },
  { study: "Overall", ratio: 0.72, low: 0.60, high: 0.87 }
]

chart :forest, studies, x: :ratio, label: :study, error: { low: :low, high: :high }, size: :n, log: :x

Survival

Kaplan–Meier curves from follow-up times and events, with a log-rank p.

cohort = dataset months: [ 3, 5, 7, 9, 12, 14, 18, 2, 4, 6, 6, 8, 15, 1 ],
  died: [ 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1 ], arm: %w[ drug ] * 7 + %w[ placebo ] * 7

chart :survival, cohort, time: :months, event: :died, color: :arm

Table

Rows as a table, numbered like figures.

baseline = dataset arm: %w[ Drug Placebo ], n: [ 152, 149 ], age: [ 61.2, 60.8 ]

table baseline, title: "Baseline", caption: "Mean age, by arm."

Every setting

In a block as title "…", or as a keyword: title: "…".

Words

title
Above the chart, bold title "Patients seen"
subtitle
Under the title subtitle "Intention to treat"
caption
Under the chart, after “Figure 1.” caption "By month, 2024."
source
Smallest, at the foot source "Clinic records"
numbered
Leave out “Figure 1.” numbered false

Axes

x, y
Which column goes on each axis x :week
y [ … ]
A line or bar per column y [ :sbp, :dbp ]
label:
The axis title y :sbp, label: "Systolic (mmHg)"
format:
How numbers read y format: :percent
from:, to:
Where the axis starts and ends y from: 0, to: 1
ticks:
Roughly how many marks x ticks: 10
scale:
:linear, :log, :date or :band x scale: :log
log
Log scale on an axis log :x
x_label: …
Any axis setting, as a keyword chart :line, d, y_label: "Mean"

Colour

color
One colour for everything color :red
color :column
A colour per value of a column color :arm
color … =>
Choose the colours color :arm, "drug" => :red, "placebo" => :faint
opacity
How solid fills are, 0 to 1 opacity 0.5

Marks on the chart

error
Error bars, or a band on a line error low: :ci_low, high: :ci_high
hline
A line across, at a value hline 0.5, label: "Target"
vline
A line up, at a value vline 8, label: "Surgery"
band
A shaded span band x: 4..8, label: "Treatment"
note
Words at a point note 10, 0.7, "Plateau"
trend
Least-squares line (scatter) trend true

Look

legend
:top, :bottom, :right, :end or :none legend :bottom
aspect
Width over height aspect 2
grid
Grid lines: false, true or :both grid :both
points
Dots on lines; values on boxes points true
width
Line width width 2
dashed
Dashed lines dashed true
size
Point or square size, or a column size :n
stack
Stack bars or areas stack true
horizontal
Bars lying down horizontal true
labels
Values on the bars labels true
bins
Bars in a histogram bins 20

Survival and forest

time, event
Follow-up, and whether the event happened time :months; event :died
logrank
Leave out the log-rank p logrank false
label
The row names in a forest plot label :study
reference
Line of no effect: 1 on log, 0 otherwise reference false

Formats

:percent
0.25 → 25%
:integer
1234.6 → 1,235
:thousands
12500 → 12,500
:decimal
two places
:scientific
1.20e+04
"%.1f mg"
printf, any way you like
->(v) { … }
a lambda

Colours

  • :ink
  • :red
  • :green
  • :blue
  • :yellow
  • :purple
  • :orange
  • :teal
  • :soft
  • :faint

Or any "#rrggbb".