Guides
Data and fields
Data inputs
Plot::of() and each geom’s data: argument accept data in several shapes:
- a list of row arrays, such as
[['x' => 1, 'y' => 2], ...] - an array of equal-length columns, such as
['x' => [1, 2], 'y' => [2, 3]] - a phibble table, or any object with
toRows()ortoColumns() - a Laravel Collection, or any object with
toArray() - any iterable of rows, where rows may be arrays or objects
Data::url('cars.csv'), which Vega-Lite fetches in the browserData::named('live'), a data source the page supplies at runtime
Inline data is embedded in the specification. Values are made safe for JSON: DateTimeInterface values become ISO 8601 strings, enums become their values, and NAN and INF become null, which Vega-Lite treats as missing.
use Phiz\Plot;
$columns = [
'month' => ['2026-01-01', '2026-02-01', '2026-03-01', '2026-04-01', '2026-05-01', '2026-06-01'],
'visits' => [1200, 1350, 1290, 1610, 1820, 1765],
];
$plot = Plot::of($columns)
->aes(x: 'month', y: 'visits')
->line()
->point(size: 50);Field types
Vega-Lite needs a measurement type for every mapped field. phiz infers it from inline data:
- quantitative, when every non-null value is an integer or a float
- temporal, when every value is an ISO date or date-time string
- nominal, otherwise
A numeric code such as a cylinder count is quantitative by this rule. It gets a continuous color scale and gradient legend unless you mark it as categorical. Field shorthand sets the type explicitly with a suffix: :Q (quantitative), :N (nominal), :O (ordinal), or :T (temporal). factor('cyl') is the equivalent of R’s factor(cyl), and its levels: argument sets the order.
use Phiz\Datasets;
use Phiz\Plot;
use function Phiz\factor;
$plot = Plot::of(Datasets::mtcars())
->aes(x: 'wt', y: 'mpg', color: factor('cyl'), shape: 'am:N')
->point(size: 60)
->labs(color: 'Cylinders', shape: 'Manual');URL data cannot be inspected in PHP, so phiz assumes quantitative positions and nominal groupings. Use shorthand types for anything else.
Aggregates and time units
Shorthand also covers Vega-Lite’s aggregates and time units: 'mean(hwy)', 'count()', 'median(price)', 'year(date):O', and 'yearmonth(date)'. The aggregation runs in Vega-Lite, grouped by the other mapped fields.
use Phiz\Datasets;
use Phiz\Plot;
$plot = Plot::of(Datasets::economics())
->aes(x: 'year(date):O', y: 'mean(psavert)')
->col(fill: '#4C78A8')
->labs(x: null, y: 'Mean personal savings rate (%)');Computed fields
calc() maps an aesthetic to a field computed from a Vega expression. The expression refers to the row as datum.
use Phiz\Datasets;
use Phiz\Plot;
use function Phiz\calc;
$plot = Plot::of(Datasets::mpg())
->aes(x: 'cty', y: calc('datum.hwy - datum.cty', as: 'gap'))
->jitter(width: 0.3, height: 0.3, alpha: 0.5, seed: 1)
->labs(x: 'City mpg', y: 'Highway minus city mpg');Field definitions
field() builds a Field with any Vega-Lite field-definition property, such as field('date', timeUnit: 'month', title: 'Month') or field('term', sort: ['b', 'a', 'c']). A raw array is also accepted for any aesthetic and is used as given.
Field names containing dots or brackets, such as R’s Sepal.Length, are escaped automatically. Vega-Lite would otherwise read them as nested access.
From phpstats/phiz@bc7ed3e.