admin管理员组

文章数量:1296421

I have the plot below, with secondary axes showing row and column totals. I want to label these as "Total". I know that I can get an axis title by altering name = NULL, but that will only appear below / to the right of the numbers. I want them in line with the other axis labels. I'd also like to show the overall total in the lower right corner.

## Code for the above plot

library(ggplot2)

# Create example data
DATA <- data.frame(
                "Top" = factor(rep(c("A", "B", "C"), each = 3)), 
                "Side" = factor(rep(c("Blue", "Green", "Red"), times = 3)), 
                "Count" = c(2,13,0,4,1,10,15,0,6))

# Calculate row and column totals
COL.TOTALS <- aggregate(DATA$Count, by = list(DATA$Top), FUN = sum)
ROW.TOTALS <- aggregate(DATA$Count, by = list(DATA$Side), FUN = sum)

# Plot
ggplot(DATA, aes(as.numeric(Top), as.numeric(Side), Count)) +
  geom_point(aes(size = Count)) +
  scale_x_continuous(position = "top", breaks = 1:3, 
                labels = levels(DATA$Top), sec.axis = dup_axis(breaks =
                as.numeric(COL.TOTALS$Group.1), labels = COL.TOTALS$x, 
                name = NULL)) +
  scale_y_continuous(breaks = 1:3, labels = levels(DATA$Side), 
                sec.axis = dup_axis(breaks = as.numeric(ROW.TOTALS$Group.1),
                labels = ROW.TOTALS$x, name = NULL))

I have the plot below, with secondary axes showing row and column totals. I want to label these as "Total". I know that I can get an axis title by altering name = NULL, but that will only appear below / to the right of the numbers. I want them in line with the other axis labels. I'd also like to show the overall total in the lower right corner.

## Code for the above plot

library(ggplot2)

# Create example data
DATA <- data.frame(
                "Top" = factor(rep(c("A", "B", "C"), each = 3)), 
                "Side" = factor(rep(c("Blue", "Green", "Red"), times = 3)), 
                "Count" = c(2,13,0,4,1,10,15,0,6))

# Calculate row and column totals
COL.TOTALS <- aggregate(DATA$Count, by = list(DATA$Top), FUN = sum)
ROW.TOTALS <- aggregate(DATA$Count, by = list(DATA$Side), FUN = sum)

# Plot
ggplot(DATA, aes(as.numeric(Top), as.numeric(Side), Count)) +
  geom_point(aes(size = Count)) +
  scale_x_continuous(position = "top", breaks = 1:3, 
                labels = levels(DATA$Top), sec.axis = dup_axis(breaks =
                as.numeric(COL.TOTALS$Group.1), labels = COL.TOTALS$x, 
                name = NULL)) +
  scale_y_continuous(breaks = 1:3, labels = levels(DATA$Side), 
                sec.axis = dup_axis(breaks = as.numeric(ROW.TOTALS$Group.1),
                labels = ROW.TOTALS$x, name = NULL))

Share Improve this question edited Feb 17 at 3:53 M-- 29.2k10 gold badges69 silver badges106 bronze badges Recognized by R Language Collective asked Feb 11 at 20:36 EcologyTomEcologyTom 2,5303 gold badges29 silver badges42 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

One option would be to use an annotation_custom (with coord_cartesian(clip="off") to draw outside of the panel) which allows for a proper placement of the labels by accounting for the length of the axis ticks and the margin of the default axis text:

library(ggplot2)

ggplot(DATA, aes(as.numeric(Top), as.numeric(Side), Count)) +
  geom_point(aes(size = Count)) +
  scale_x_continuous(
    position = "top", breaks = 1:3,
    labels = levels(DATA$Top), sec.axis = dup_axis(
      breaks =
        as.numeric(COL.TOTALS$Group.1), labels = COL.TOTALS$x,
      name = NULL
    )
  ) +
  scale_y_continuous(
    breaks = 1:3, labels = levels(DATA$Side),
    sec.axis = dup_axis(
      breaks = as.numeric(ROW.TOTALS$Group.1),
      labels = ROW.TOTALS$x, name = NULL
    )
  ) +
  coord_cartesian(clip = "off") +
  annotation_custom(
    grid::textGrob(
      c("Total", "Total", sum(ROW.TOTALS$x)),
      x = unit(c(0, 1, 1), "npc") +
        unit(2.75 * c(-1, 1, 1), "pt") + # Account for tick length
        unit(2.2 * c(-1, 1, 1), "pt"), # Account for axis text margin
      y = unit(c(0, 1, 0), "npc") +
        unit(2.75 * c(-1, 1, -1), "pt") +
        unit(2.2 * c(-1, 1, -1), "pt"),
      vjust = c(1, 0, 1),
      hjust = c(1, 0, 0),
      gp = grid::gpar(
        col = "blue", 
        fontsize = .8 * 11 # Default axis text font size
      )
    )
  )

本文标签: rggplot secondary axis title positionStack Overflow