data(gapminder_2007) + point + x(gdp) + y(life)data(gapminder_2007) + point + x(col.gdp) + y(col.life)data(gapminder_2007) + point + x(:gdp) + y(:life)plot(data(gapminder_2007), point, x(col.gdp), y(col.life))You have two columns. Do they move together, or do they differ by group? The questions split by type: two measurements ask about relationship; a category and a measurement ask about comparison.
Layer a derived line over the points; + stacks layers in one panel, and * smooth fits where the cloud is heading:
data(gapminder_2007) + x(gdp) + y(life) +
point + color(continent) +
line * smooth(data(gapminder_2007) + x(col.gdp) + y(col.life) +
point + color(col.continent) +
line * smooth)data(gapminder_2007) + x(:gdp) + y(:life) + point + color(:continent) +
line * smoothplot(data(gapminder_2007), x(col.gdp), y(col.life), point,
color(col.continent), layer(line, smooth))The positions are written before any mark, so both layers share them; color is written after point, so only the points split. Encoding scope owns that rule.
A line says where the value went; an area says how much there was. It fills to zero so the quantity is the ink:
data(actuals) + area + x(year) + y(sales)data(actuals) + area + x(col.year) + y(col.sales)data(actuals) + area + x(:year) + y(:sales)plot(data(actuals), area, x(col.year), y(col.sales))One atom away. If zero is not a meaningful floor for your variable, you wanted line, not area.
A category and a measurement, summarized. The aggregation family (mean, median, sum, max, min) all read a bound y and collapse each group to one number:
data(gapminder_2007) + bar * mean + x(continent) + y(life)data(gapminder_2007) + bar * mean + x(col.continent) + y(col.life)data(gapminder_2007) + bar * mean + x(:continent) + y(:life)plot(data(gapminder_2007), layer(bar, mean), x(col.continent),
y(col.life))One atom away. Robust to outliers? Swap the word:
data(gapminder_2007) + bar * median + x(continent) + y(life)data(gapminder_2007) + bar * median + x(col.continent) + y(col.life)data(gapminder_2007) + bar * median + x(:continent) + y(:life)plot(data(gapminder_2007), layer(bar, median), x(col.continent),
y(col.life))Summaries hide spread. The strip plot is the same sentence with the derivation removed. One dot per row, stacked over each category’s slot:
data(gapminder_2007) + point + x(continent) + y(life)data(gapminder_2007) + point + x(col.continent) + y(col.life)data(gapminder_2007) + point + x(:continent) + y(:life)plot(data(gapminder_2007), point, x(col.continent), y(col.life))When the dots pile onto one line, * jitter spreads them sideways, along the category axis only, so every dot keeps its exact height:
data(gapminder_2007) + point * jitter + x(continent) + y(life) + style(opacity = 0.6)data(gapminder_2007) + point * jitter + x(col.continent) + y(col.life) + style(opacity = 0.6)data(gapminder_2007) + point * jitter + x(:continent) + y(:life) +
style(opacity = 0.6)plot(data(gapminder_2007), layer(point, jitter), x(col.continent),
y(col.life), style({ opacity: 0.6 }))One atom away. Swap the positions and the strips lie down, useful when the category names are long. See Point and jitter.
When the table already holds one value per category, no transform is involved; bar draws data as it arrives:
data(medals) + bar + x(country) + y(gold)data(medals) + bar + x(col.country) + y(col.gold)data(medals) + bar + x(:country) + y(:gold)plot(data(medals), bar, x(col.country), y(col.gold))One atom away. Ranked, because comparison reads best sorted:
data(medals) + bar + x(country) + y(gold) + order(gold, desc = TRUE)data(medals) + bar + x(col.country) + y(col.gold) + order(col.gold, desc = True)data(medals) + bar + x(:country) + y(:gold) + order(:gold, desc = true)plot(data(medals), bar, x(col.country), y(col.gold),
order(col.gold, { desc: true }))There is no hidden counting here to surprise you: if you want a computation, you write its name. That is why this recipe and How many of each? are different sentences.
A bar needs exactly one of its axes to be a number. Two categories give it nothing to measure, and the refusal points at the counting derivation:
data(gapminder_2007) + bar + x(country) + y(continent)Error:
! gog: `bar` has categorical columns on both axes — `x(country)` and `y(continent)` — so there is nothing for it to measure. One axis must be a number: that is the length of the bar. To count rows per category instead, use `bar * count`.
gog: nothing was rendered. Fix the above, or set GOG_STRICT=0 to draw anyway.