phiz

Guides

Scales, coordinates, and labels

Scales

scaleX(), scaleY(), scaleColor(), scaleFill(), scaleSize(), scaleShape(), scaleOpacity(), and scaleLinetype() configure the scale and guide for one aesthetic. Successive calls for the same aesthetic merge.

Scale options are passed to the Vega-Lite scale:

  • type: linear, log, sqrt, pow, symlog, time, ordinal, quantile, quantize, or threshold
  • domain and range
  • scheme, a Vega color scheme such as viridis, blues, set2, or tableau10
  • values, a manual palette as a level-to-value map or a list in level order
  • zero, nice, reverse, clamp, base, exponent, domainMid, and padding

Guide options are passed to the axis or legend:

  • name, the title
  • breaks, the tick or legend values
  • format, a d3 number or time format
  • labels, a label formatter (below), a map from values to labels, a list of labels for breaks, or a Vega label expression
  • guide: false, which hides the axis or legend
use Phiz\Datasets;
use Phiz\Plot;

$plot = Plot::of(Datasets::economics())
    ->aes(x: 'pop', y: 'pce')
    ->point(alpha: 0.4)
    ->scaleY(type: 'log', breaks: [500, 1000, 2000, 5000, 10000], name: 'Personal consumption ($bn, log scale)')
    ->scaleX(format: '.3s', name: 'Population (thousands)');
use Phiz\Datasets;
use Phiz\Plot;

$plot = Plot::of(Datasets::mpg())
    ->aes(x: 'displ', y: 'hwy', color: 'drv')
    ->point(size: 40)
    ->scaleColor(values: ['f' => '#1B9E77', 'r' => '#7570B3', '4' => '#D95F02'], name: 'Drive');

Continuous position scales fit the data as in ggplot2: points and lines do not force the axis to include zero. Plots with bars, areas, histograms, or densities keep zero, since their lengths are measured from it. zero: true restores Vega-Lite’s default for a single scale.

The functions in Phiz\ include ggplot2’s shortcuts. Each returns a closure for the pipe operator or apply():

Function Scale
scale_x_log10(), scale_x_sqrt(), scale_x_reverse(), scale_x_date() transformed and date position scales
scale_x_discrete(limits:, labels:) discrete positions: limits orders and subsets the levels, labels renames them
scale_color_manual(values) a level-to-color map, or colors in level order
scale_color_brewer(palette), scale_color_distiller(), scale_color_fermenter() ColorBrewer palettes for discrete, continuous, and binned data
scale_color_viridis_d(), _c(), _b() viridis with option (A magma to E cividis, H turbo), begin, end, and direction
scale_color_gradient(), scale_color_gradient2(), scale_color_gradientn() two-color, diverging, and many-color gradients
scale_color_hue(h:, c:, l:, hStart:, direction:) ggplot2’s hue palette with its options
scale_color_grey(start:, end:) grays, as grey.colors()
scale_color_identity() the data values are the colors, with no legend

Each scale_color_*() has a scale_fill_*() twin. The hue and grey palettes are computed for the number of levels in the data.

Label formatters

The label functions follow the scales package. Pass one as labels:.

Function 0.256 12500
label_percent() 25.6% 1250000%
label_comma() 0.256 12,500
label_dollar() $0.256 $12,500
label_number(accuracy: 0.1, suffix: ' kg') 0.3 kg 12,500.0 kg
label_scientific() 2.56e-1 1.25e+4
label_date('%b %Y') for dates

accuracy rounds (0.01 keeps two decimals, and the default trims trailing zeros), scale multiplies first, and prefix and suffix wrap the number. label_dollar(scale: 0.001, suffix: 'k') writes 12500 as $12.5k.

use Phiz\Datasets;
use Phiz\Plot;

use function Phiz\guide_axis;
use function Phiz\label_percent;
use function Phiz\scale_fill_viridis_d;

$plot = Plot::of(Datasets::mpg())
    ->aes(x: 'class', fill: 'drv')
    ->bar(position: 'fill')
    ->scaleY(labels: label_percent(), name: 'Share of cars')
    ->apply(scale_fill_viridis_d(begin: 0.2, end: 0.8))
    ->guides(x: guide_axis(angle: 45))
    ->labs(x: null, fill: 'Drive');

Guides

guides() sets the axis or legend for each aesthetic, as ggplot2’s guides() does. 'none' hides one. guide_axis(angle:) turns axis labels, guide_legend(title:, ncol:, direction:) arranges a legend, and guide_colorbar(barwidth:, barheight:) sizes a color bar. Any other Vega-Lite axis or legend property can be passed as a named argument.

guide_axis(cap: true) draws the axis line only from the first break to the last, as ggplot2’s guide_axis(cap = "both") does. With a padded domain, such as scaleX(domain: [-4, 104], breaks: [0, 20, 40, 60, 80, 100]), the line stops at 0 and 100 and stands apart from the panel corners. It needs breaks or a domain. Faceted plots do not support it, because the line would be drawn in every panel.

use Phiz\Datasets;
use Phiz\Plot;

use function Phiz\scale_color_grey;
use function Phiz\scale_x_discrete;

$plot = Plot::of(Datasets::mpg())
    ->aes(x: 'drv', y: 'hwy', color: 'drv')
    ->boxplot()
    ->apply(scale_x_discrete(limits: ['f', 'r', '4'], labels: ['f' => 'Front', 'r' => 'Rear', '4' => '4WD']))
    ->apply(scale_color_grey())
    ->guides(color: 'none')
    ->labs(x: 'Drive', y: 'Highway mpg')
    ->theme('bw');

Coordinates

coordFlip() turns the plot sideways while the mappings stay as written. This is the usual way to give long category labels room.

use Phiz\Datasets;
use Phiz\Plot;

$plot = Plot::of(Datasets::mpg())
    ->aes(x: 'manufacturer', y: 'hwy')
    ->boxplot(fill: '#C6DBEF')
    ->coordFlip()
    ->labs(x: null, y: 'Highway mpg');

coordCartesian(xlim:, ylim:), xlim(), and ylim() fix the domains and clip marks outside them. ggplot2’s xlim() removes the data outside the limits, which changes statistics such as smoothers. phiz keeps the data and only zooms.

coordFixed(ratio) fixes the aspect ratio, as coord_fixed() does: one unit of y takes ratio times the length of one unit of x. The panel’s height follows from its width (300 pixels unless set) and the data ranges, and the scales keep those ranges exactly. coord_equal() is the same with a ratio of 1.

use Phiz\Datasets;
use Phiz\Plot;

$plot = Plot::of(Datasets::mpg())
    ->aes(x: 'cty', y: 'hwy')
    ->point(alpha: 0.5)
    ->abline(color: 'gray', linetype: 'dashed')
    ->coordFixed()
    ->labs(x: 'City mpg', y: 'Highway mpg');

coordPolar() draws bar() and col() layers in polar coordinates. theta: 'y' stacks the bars into a pie (leave x unmapped, or map it to a constant), and innerRadius: in pixels makes a donut. theta: 'x' makes a rose: one equal slice per level of x, with radius y. start: rotates the first slice clockwise from twelve o’clock, in radians, and direction: -1 runs anticlockwise. Other geoms have no polar form in Vega-Lite, and phiz rejects them.

use Phiz\Compose;
use Phiz\Datasets;
use Phiz\Plot;

$cars = Plot::of(Datasets::mpg());

$plot = Compose::beside(
    $cars->aes(fill: 'class')->bar()->coordPolar(theta: 'y')->title('Pie'),
    $cars->aes(x: 'class', fill: 'class')->bar()->coordPolar()->title('Rose'),
)->resolve(['scale' => ['theta' => 'independent', 'radius' => 'independent']]);

Labels

labs() sets the title, subtitle, caption, and the title for any aesthetic. A null title removes it. Titles for position aesthetics apply to everything drawn on that axis, including ranges and reference lines. A facet field’s name sets its panel header title.

$plot->labs(title: 'Fuel economy', subtitle: 'EPA data, 1999 and 2008', x: 'Displacement (L)', y: 'Highway mpg', color: 'Drive');

The caption is placed below the plot, under the axis titles. By default it is right-aligned and smaller than the axis titles, as in ggplot2. theme(captionSize:, captionColor:, captionAnchor:) changes its size, color, and alignment (start, middle, or end). Vega-Lite gives each view one title. A plot with both a title and a caption is therefore emitted as a vconcat that holds the single view, with the title on the outside and the caption on the view. Vega-Lite does not apply autosize fit to a vconcat. In such a plot, size() sets the plot area alone, and the titles, axes, and caption are added around it. A caption without a title keeps the exact size under autosize fit.

From phpstats/phiz@bc7ed3e.