Skip to contents

In ggcube, standard ggplot2 themes generally influence 3D plots as expected, including adding complete themes like ggplot2::theme_dark() and modifying theme elements like theme(panel.background = element_rect(fill = "darkblue"). However, ggcube also provides additional theme elements that control 3D-specific styling of panels and labels.

Text elements

  • axis.text.z: Styling for z-axis tick labels (inherits from axis.text)

  • axis.title.z: Styling for z-axis title (inherits from axis.title)

  • axis.text, axis.title: Standard styling with element_text().

Use element_text(margin = margin(...)) to adjust text padding, with left/right margins affecting axis text and top/bottom margins affecting axis titles; since placement and justification of these elements varies dynamically, no distinction is made between left and right margins, or between top and bottom margins – you can set either, and the maximum of the two will be used.

Axis ticks

  • axis.ticks.z: Styling for z-axis ticks (inherits from axis.ticks)

  • axis.ticks, axis.ticks.x, axis.ticks.y: Standard styling with element_line().

  • axis.ticks.length, axis.ticks.length.x/y/z: Tick length.

Ticks are 3D geometry rather than screen-space annotation: each one continues its gridline past the cube edge, and is projected like everything else. They therefore foreshorten with the view, and a tick pointing away from the viewer is drawn shorter than one lying across it.

Because of this, axis.ticks.length is an upper bound rather than an exact length. It is calibrated so that a tick along the least foreshortened axis renders at the requested size, with ticks along the other axes coming in shorter. Tick length does not vary with axis ratio; a stretched axis gets the same ticks as a compressed one.

As in 2D ggplot2, axis.ticks.length also contributes to the spacing between the cube and the axis text, whether or not ticks are drawn. Setting axis.ticks = element_blank() removes the ticks but leaves that spacing intact; set axis.ticks.length = unit(0, "pt") to close the gap as well. Negative lengths point ticks inward, and do not displace the axis text.

Panel elements

  • panel.foreground: Styling for cube faces rendered in front of data (inherits from panel.background). Foreground panels default to 20% opacity to keep them from obscuring the data; this can be overridden by setting alpha on either panel.foreground or panel.background.

  • panel.border.foreground: Styling for cube faces rendered in front of data (inherits from panel.border)

  • panel.grid.foreground: Styling for grid lines on foreground faces (inherits from panel.grid)

  • panel.grid.major.foreground: Major grid lines on foreground faces (inherits from panel.grid.foreground)

Background panels use standard panel.background, panel.border, panel.grid, etc., while foreground panels use the *.foreground variants listed above. Since the foreground elements inherit from the standard background and grid elements, you can use panel.background, etc. to style both background and foreground faces simultaneously. This also extends to alpha set via the enhanced element_rect() below: setting alpha on panel.background will tint both background and foreground panels (overriding the foreground's 20% default), unless an explicit alpha is also set on panel.foreground.

Depth scaling

Under perspective projection, gridlines, borders, ticks, and axis text are (by default) sized by their distance from the viewer. An element at the center of the cube renders at exactly the size the theme specifies, with nearer elements drawn larger and farther ones smaller. Axis titles are never scaled this way, and orthographic plots are unaffected. You can use coord_3d(scale_depth = ) to reduce or disable the depth-scaling effect, per element or globally.

Enhanced elements

Examples

# example code
p <- ggplot(sphere_points, aes(x, y, z)) +
  geom_hull_3d() +
  coord_3d(panels = "all") +
  theme(panel.background = element_rect(color = "black"),
          panel.border = element_rect(color = "black"),
          panel.foreground = element_rect(alpha = .3),
          panel.grid.foreground = element_line(color = "gray", linewidth = .25),
          axis.text = element_text(color = "darkblue"),
          axis.text.z = element_text(color = "darkred"),
          axis.title = element_text(margin = margin(t = 30)), # add padding
          axis.title.x = element_text(color = "magenta"))