wake-up-neo.com

Mehrzeilige X-Achsenbeschriftungen im ggplot-Liniendiagramm

Edit: Diese Frage wurde als doppelt markiert, aber die Antworten hier wurden versucht und haben nicht funktioniert, da es sich bei dem betreffenden Fall um ein Liniendiagramm und nicht um ein Balkendiagramm handelt. Die Anwendung dieser Methoden führt zu einem Diagramm mit 5 Zeilen, 1 für jedes Jahr - nicht sinnvoll. Hat jemand, der dafür gestimmt hat, als Duplikat zu stimmen, diese Ansätze im Beispieldatensatz, der mit dieser Frage geliefert wurde, tatsächlich versucht? Wenn ja, bitte als Antwort posten.

Ursprüngliche Frage:

Es gibt eine Funktion in Excel-Pivot-Diagrammen, die mehrstufige kategoriale Achsen ermöglicht. Ich versuche, mit ggplot (oder einem anderen Plotpaket in R) dasselbe zu tun.

Betrachten Sie den folgenden Datensatz:

set.seed(1)
df=data.frame(year=rep(2009:2013,each=4),
              quarter=rep(c("Q1","Q2","Q3","Q4"),5),
              sales=40:59+rnorm(20,sd=5))

Wenn diese in eine Excel-Pivot-Tabelle importiert wird, können Sie das folgende Diagramm problemlos erstellen:

Beachten Sie, dass die x-Achse zwei Ebenen hat, eine für Quartal und eine für die Gruppierungsvariable, Jahr. Sind mit ggplot mehrstufige Achsen möglich?

NB: Es gibt einen Hack mit Facetten, der etwas Ähnliches hervorbringt, aber das ist es nicht, wonach ich suche.

library(ggplot2)
ggplot(df) +
  geom_line(aes(x=quarter,y=sales,group=year))+
  facet_grid(.~year,scales="free")

39
jlhoward

Wir verwenden Argumente in theme, um den Standardtext der X-Achse (axis.title.x/axis.text.x = element_blank()) zu entfernen, und zusätzliche Ränder werden hinzugefügt (plot.margin).

Neue Labels werden mit annotate(geom = "text", hinzugefügt. Durch die Konvertierung des Plotobjekts in ein Grob (ggplot_gtable(ggplot_build() kann das Beschneiden von Beschriftungen der X-Achse deaktiviert werden. 

library(ggplot2)
g1 <- ggplot(data = df, aes(x = interaction(year, quarter, Lex.order = TRUE), 
                            y = sales, group = 1)) +
  geom_line(colour = "blue") +
  coord_cartesian(ylim = c(35, 65), expand = FALSE) +
  annotate(geom = "text", x = seq_len(nrow(df)), y = 34, label = df$quarter, size = 4) +
  annotate(geom = "text", x = 2.5 + 4 * (0:4), y = 32, label = unique(df$year), size = 6) +
  theme_bw() +
  theme(plot.margin = unit(c(1, 1, 4, 1), "lines"),
        axis.title.x = element_blank(),
        axis.text.x = element_blank(),
        panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank())


# remove clipping of x axis labels
g2 <- ggplot_gtable(ggplot_build(g1))
g2$layout$clip[g2$layout$name == "panel"] <- "off"
grid::grid.draw(g2)

 enter image description here


Siehe auch die Nice-Antwort von @ eipi10 hier: Achsenbeschriftungen in zwei Zeilen mit verschachtelten x-Variablen (Jahr unter Monaten)

44
Henrik

Der vorgeschlagene Code von Henrik funktioniert und hat mir sehr geholfen! Ich denke, die Lösung hat einen hohen Wert. Bitte beachten Sie jedoch, dass in der ersten Codezeile ein kleiner Fehler auftritt, der zu einer falschen Reihenfolge der Daten führt. Anstatt

... aes(x = interaction(year,quarter), ...

es sollte sein

... aes(x = interaction(quarter,year), ...

Die resultierende Grafik weist die Daten in der richtigen Reihenfolge auf.

enter image description here

P.S. Ich schlug eine Bearbeitung vor (die bisher abgelehnt wurde), und ich darf, aufgrund eines geringen Rufs, nicht kommentieren, was ich lieber getan hätte.

26
VDK

Benutzer Tung hatte eine großartige Antwort zu diesem Thread

library(tidyverse)
library(lubridate)
library(scales)

set.seed(123)
df <- tibble(
  date = as.Date(41000:42000, Origin = "1899-12-30"), 
  value = c(rnorm(500, 5), rnorm(501, 10))
)

# create year column for facet
df <- df %>% 
  mutate(year = as.factor(year(date)))

p <- ggplot(df, aes(date, value)) + 
  geom_line() + 
  geom_vline(xintercept = as.numeric(df$date[yday(df$date) == 1]), color = "grey60") + 
  scale_x_date(date_labels = "%b", 
               breaks = pretty_breaks(),
               expand = c(0, 0)) +
  # switch the facet strip label to the bottom
  facet_grid(.~ year, space = 'free_x', scales = 'free_x', switch = 'x') +
  labs(x = "") +
  theme_classic(base_size = 14, base_family = 'mono') +
  theme(panel.grid.minor.x = element_blank()) + 
  # remove facet spacing on x-direction
  theme(panel.spacing.x = unit(0,"line")) +
  # switch the facet strip label to outside 
  # remove background color
  theme(strip.placement = 'outside',
        strip.background.x = element_blank())
p

 Image

0
stackinator