Skip to content

Axis Labels

Dataface keeps the encoded axis time unit stable while adapting crowded x-axis labels. Bucketed temporal axes first choose the finest fitting label format, then thin visibility, then tilt the labels that remain. Font size does not change.

Automatic layout

The renderer resolves label layout from the axis type, available width, and formatted label widths:

Axis Automatic behavior
Quantitative x-axis Keep labels horizontal and let Vega-Lite place ticks
Bucketed temporal x-axis Choose the finest fitting calendar vocabulary, thin its visibility if needed, then tilt
Cyclic temporal x-axis Drop alternating labels, then tilt if needed
Categorical x-axis Keep every label, then tilt if needed
Horizontal bar category axis Keep labels horizontal

Bucket-aligned daily axes and detected weekly axes first use compact day-number labels. Daily labels can step from every day to Mondays, then to month text; weekly labels step from every week to month text. Continuous weekly line and area axes keep Vega's tick positions but label each Sunday boundary with the represented ISO Monday bucket. After that vocabulary is chosen, visibility thinning follows meaningful calendar periods. Monthly text, for example, can appear only at quarter-opening months. The fiscal year start month anchors quarter and year boundaries.

Automatic format promotion changes the default tick cadence but not the encoded data grain. Later width-dependent visibility thinning changes only which labels are visible. It does not change:

  • the encoding time_unit,
  • the underlying ticks, or
  • the chart data.

An explicitly authored label.time_unit is different: it selects both the label vocabulary and the default tick cadence. For example, label.time_unit: yearquarter on monthly data emits quarter labels and quarter ticks. Author axis_x.ticks to override that default on a continuous temporal axis.

If the thinned labels still collide, Dataface tries the configured tilt_increments from the shallowest angle to the steepest.

Configure overlap resolution

label.overlap has two boolean switches. Their execution order is fixed: skip, then tilt.

style:
  axis_x:
    label:
      overlap:
        skip: true
        tilt: true

Disable tilt to keep retained labels horizontal:

style:
  axis_x:
    label:
      overlap:
        skip: true
        tilt: false

Disable both strategies to keep every label visible even when labels collide:

style:
  axis_x:
    label:
      overlap:
        skip: false
        tilt: false

An explicit label.angle takes precedence and bypasses automatic overlap resolution:

style:
  axis_x:
    label:
      angle: -45

Temporal labels

axis_x.time_unit controls the data encoding grain. The resolved label.time_unit controls the label text format and default tick cadence, whether it was authored or chosen automatically. Automatic daily labels use the finest fitting format on bucket-aligned axes; weekly labels use the same compact vocabulary on continuous line and area axes. Width-dependent visibility thinning after format selection changes neither the format nor ticks.

style:
  axis_x:
    time_unit: yearmonth
    fiscal_year_start_month: 3
    label:
      time_unit: yearmonth

For this axis, labels still use month text. When space is tight, only the fiscal-quarter opening months are shown: March, June, September, and December. The axis remains monthly.

Cyclic units such as monthofyear, dayofweek, and hourofday do not have a coarser chronological period. They use alternating-label thinning before tilt.

See Time Axes for time-unit detection, formatting, and fiscal calendar behavior.

Tilt candidates

Themes configure the angles considered after thinning with tilt_increments:

style:
  charts:
    axis_x:
      label:
        tilt_increments: [0, -30, -45, -60, -90]

Order matters. Dataface uses the first angle whose projected width fits. This is a theme-level knob; chart authors normally use label.angle when they need one exact rotation.

Bar orientation

With style.orientation: auto, categorical bar charts render horizontally. Their category labels move to the y-axis and remain horizontal. Temporal, quantitative, and time-unit-bucketed bars remain vertical.

Set an orientation explicitly to override that choice:

charts:
  revenue_by_state:
    type: bar
    x: state_name
    y: revenue
    style:
      orientation: vertical

Other label controls

Hide labels:

style:
  axis_y:
    label:
      visible: false

Control truncation:

style:
  axis_x:
    label:
      max_width: 240

Add separation between adjacent labels:

style:
  axis_x:
    label:
      separation: 24

Mirrored Y-Axis

Set style.axis_y.mirror: true on a wide cartesian chart to draw the y-scale on both the left and right edges. Both edges share the same scale and ticks. This is a readability aid, not a second scale.

source: examples_db
charts:
  revenue_wide:
    query:
      sql: |
        SELECT date, SUM(revenue) AS revenue
        FROM ecommerce_orders
        GROUP BY date
        ORDER BY date
    type: line
    title: Daily Revenue
    x: date
    y: revenue
    style:
      axis_y:
        mirror: true
rows:
  - revenue_wide
1 Jan20242 Jan3 Jan4 Jan5 Jan6 Jan7 Jan8 Jan9 Jan10 Jan11 Jan12 Jan13 Jan14 Jan15 Jan16 Jan17 Jan18 Jan19 Jan20 Jan21 Jan22 Jan23 Jan24 Jan25 Jan26 Jan27 Jan28 Jan29 Jan30 Jan010k20k30k010k20k30kRevenueDaily Revenue Data as of 16:49 UTC on 5 Aug 2026 made with dataface

Pass an object instead of true to relabel the mirrored edge:

style:
  axis_y:
    mirror:
      format: ".0%"

format and expr are mutually exclusive. Neither changes the scale or tick placement.

This differs from a layered chart with independent left and right axes. A mirrored axis draws one scale twice.