Ich habe die folgenden Daten ( temp.dat
vollständige Daten siehe Endnote)
Year State Capex
1 2003 VIC 5.356415
2 2004 VIC 5.765232
3 2005 VIC 5.247276
4 2006 VIC 5.579882
5 2007 VIC 5.142464
...
und ich kann die folgende Tabelle erstellen:
ggplot(temp.dat) +
geom_line(aes(x = Year, y = Capex, group = State, colour = State))
Anstelle der Legende möchte ich die Etiketten haben
- farbig wie die Serie
- rechts vom letzten Datenpunkt für jede Serie
Ich habe die Kommentare von baptiste in der Antwort im folgenden Link bemerkt, aber wenn ich versuche, seinen Code ( geom_text(aes(label = State, colour = State, x = Inf, y = Capex), hjust = -1)
) anzupassen, wird der Text nicht angezeigt.
ggplot2 - außerhalb des Plots mit Anmerkungen versehen
temp.dat <- structure(list(Year = c("2003", "2004", "2005", "2006", "2007",
"2008", "2009", "2010", "2011", "2012", "2013", "2014", "2003",
"2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011",
"2012", "2013", "2014", "2003", "2004", "2005", "2006", "2007",
"2008", "2009", "2010", "2011", "2012", "2013", "2014", "2003",
"2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011",
"2012", "2013", "2014"), State = structure(c(1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L), .Label = c("VIC",
"NSW", "QLD", "WA"), class = "factor"), Capex = c(5.35641472365348,
5.76523240652641, 5.24727577535625, 5.57988239709746, 5.14246402568366,
4.96786288162828, 5.493190785287, 6.08500616799372, 6.5092228474591,
7.03813541623157, 8.34736513875897, 9.04992300432169, 7.15830329914056,
7.21247045701994, 7.81373928617117, 7.76610217197542, 7.9744994967006,
7.93734452080786, 8.29289899132255, 7.85222269563982, 8.12683746325074,
8.61903784301649, 9.7904327253813, 9.75021175267288, 8.2950673974226,
6.6272705639724, 6.50170524635367, 6.15609626379471, 6.43799637295979,
6.9869551384028, 8.36305663640294, 8.31382617231745, 8.65409824343971,
9.70529678167458, 11.3102788081848, 11.8696420977237, 6.77937303542605,
5.51242844820827, 5.35789621712839, 4.38699327451101, 4.4925792218211,
4.29934654081527, 4.54639175257732, 4.70040615159951, 5.04056109514957,
5.49921208937735, 5.96590909090909, 6.18700407463007)), class = "data.frame", row.names = c(NA,
-48L), .Names = c("Year", "State", "Capex"))
geom_text(data = temp.dat[cumsum(table(temp.dat$State)), ], aes(label = State, colour = State, x = Year, y = Capex))
aber es gibt möglicherweise eine bessere Möglichkeit, Dinge zu tunAntworten:
Um Baptistes Idee zu verwenden, müssen Sie das Abschneiden deaktivieren. Aber wenn Sie das tun, bekommen Sie Müll. Darüber hinaus müssen Sie die Legende unterdrücken und für
geom_text
Capex für 2014 auswählen und den Rand erhöhen, um Platz für die Beschriftungen zu schaffen. (Oder Sie können denhjust
Parameter anpassen , um die Beschriftungen im Plotfenster zu verschieben.) So etwas:library(ggplot2) library(grid) p = ggplot(temp.dat) + geom_line(aes(x = Year, y = Capex, group = State, colour = State)) + geom_text(data = subset(temp.dat, Year == "2014"), aes(label = State, colour = State, x = Inf, y = Capex), hjust = -.1) + scale_colour_discrete(guide = 'none') + theme(plot.margin = unit(c(1,3,1,1), "lines")) # Code to turn off clipping gt <- ggplotGrob(p) gt$layout$clip[gt$layout$name == "panel"] <- "off" grid.draw(gt)
Aber das ist die Art von Handlung, für die es perfekt ist
directlabels
.library(ggplot2) library(directlabels) ggplot(temp.dat, aes(x = Year, y = Capex, group = State, colour = State)) + geom_line() + scale_colour_discrete(guide = 'none') + scale_x_discrete(expand=c(0, 1)) + geom_dl(aes(label = State), method = list(dl.combine("first.points", "last.points")), cex = 0.8)
Bearbeiten So vergrößern Sie den Abstand zwischen dem Endpunkt und den Beschriftungen:
ggplot(temp.dat, aes(x = Year, y = Capex, group = State, colour = State)) + geom_line() + scale_colour_discrete(guide = 'none') + scale_x_discrete(expand=c(0, 1)) + geom_dl(aes(label = State), method = list(dl.trans(x = x + 0.2), "last.points", cex = 0.8)) + geom_dl(aes(label = State), method = list(dl.trans(x = x - 0.2), "first.points", cex = 0.8))
quelle
directlabels
Paket. In der Dokumentation konnte ich keine Möglichkeit finden, den horizontalen Abstand zwischen den Endpunkten und der Textbeschriftung manuell zu vergrößern. Was ist der beste Weg, dies zu tun?package ‘directlabels’ is not available (for R version 3.3.2)
. Ich kann die FAQ-Seite für das Paket ebenfalls nicht finden. Lebt es noch?quadprog
?Eine neuere Lösung ist zu verwenden
ggrepel
:library(ggplot2) library(ggrepel) library(dplyr) temp.dat %>% mutate(label = if_else(Year == max(Year), as.character(State), NA_character_)) %>% ggplot(aes(x = Year, y = Capex, group = State, colour = State)) + geom_line() + geom_label_repel(aes(label = label), nudge_x = 1, na.rm = TRUE)
quelle
Diese Frage ist alt, aber goldfarben, und ich gebe eine andere Antwort für müde Leute.
Das Prinzip dieser Lösung kann ganz allgemein angewendet werden.
Plot_df <- temp.dat %>% mutate_if(is.factor, as.character) %>% # Who has time for factors.. mutate(Year = as.numeric(Year))
Und jetzt können wir unsere Daten unterteilen
ggplot() + geom_line(data = Plot_df, aes(Year, Capex, color = State)) + geom_text(data = Plot_df %>% filter(Year == last(Year)), aes(label = State, x = Year + 0.5, y = Capex, color = State)) + guides(color = FALSE) + theme_bw() + scale_x_continuous(breaks = scales::pretty_breaks(10))
Der letzte Teil von pretty_breaks dient nur dazu, die Achse darunter zu fixieren.
quelle
Sie sind sich nicht sicher, ob dies der beste Weg ist, aber Sie können Folgendes versuchen (spielen Sie ein wenig
xlim
damit, um die Grenzwerte richtig einzustellen):library(dplyr) lab <- tapply(temp.dat$Capex, temp.dat$State, last) ggplot(temp.dat) + geom_line(aes(x = Year, y = Capex, group = State, colour = State)) + scale_color_discrete(guide = FALSE) + geom_text(aes(label = names(lab), x = 12, colour = names(lab), y = c(lab), hjust = -.02))
quelle
Sie haben die Lösung von @ Baptiste nicht zu 100% emuliert. Sie müssen
annotation_custom
alle Ihre verwenden und durchlaufenCapex
:library(ggplot2) library(dplyr) library(grid) temp.dat <- structure(list(Year = c("2003", "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2003", "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2003", "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2003", "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014"), State = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L), .Label = c("VIC", "NSW", "QLD", "WA"), class = "factor"), Capex = c(5.35641472365348, 5.76523240652641, 5.24727577535625, 5.57988239709746, 5.14246402568366, 4.96786288162828, 5.493190785287, 6.08500616799372, 6.5092228474591, 7.03813541623157, 8.34736513875897, 9.04992300432169, 7.15830329914056, 7.21247045701994, 7.81373928617117, 7.76610217197542, 7.9744994967006, 7.93734452080786, 8.29289899132255, 7.85222269563982, 8.12683746325074, 8.61903784301649, 9.7904327253813, 9.75021175267288, 8.2950673974226, 6.6272705639724, 6.50170524635367, 6.15609626379471, 6.43799637295979, 6.9869551384028, 8.36305663640294, 8.31382617231745, 8.65409824343971, 9.70529678167458, 11.3102788081848, 11.8696420977237, 6.77937303542605, 5.51242844820827, 5.35789621712839, 4.38699327451101, 4.4925792218211, 4.29934654081527, 4.54639175257732, 4.70040615159951, 5.04056109514957, 5.49921208937735, 5.96590909090909, 6.18700407463007)), class = "data.frame", row.names = c(NA, -48L), .Names = c("Year", "State", "Capex")) temp.dat$Year <- factor(temp.dat$Year) color <- c("#8DD3C7", "#FFFFB3", "#BEBADA", "#FB8072") gg <- ggplot(temp.dat) gg <- gg + geom_line(aes(x=Year, y=Capex, group=State, colour=State)) gg <- gg + scale_color_manual(values=color) gg <- gg + labs(x=NULL) gg <- gg + theme_bw() gg <- gg + theme(legend.position="none") states <- temp.dat %>% filter(Year==2014) for (i in 1:nrow(states)) { print(states$Capex[i]) print(states$Year[i]) gg <- gg + annotation_custom( grob=textGrob(label=states$State[i], hjust=0, gp=gpar(cex=0.75, col=color[i])), ymin=states$Capex[i], ymax=states$Capex[i], xmin=states$Year[i], xmax=states$Year[i]) } gt <- ggplot_gtable(ggplot_build(gg)) gt$layout$clip[gt$layout$name == "panel"] <- "off" grid.newpage() grid.draw(gt)
(Sie möchten das Gelb ändern, wenn Sie den weißen Hintergrund beibehalten.)
quelle
Ich möchte eine Lösung für Fälle hinzufügen, in denen Sie längere Markennamen haben. In allen bereitgestellten Lösungen befinden sich die Beschriftungen im Plotbereich. Wenn Sie jedoch längere Namen haben, werden sie abgeschnitten. So habe ich dieses Problem gelöst:
library(tidyverse) # Make the "State" variable have longer levels temp.dat <- temp.dat %>% mutate(State = paste0(State, '-a-long-string')) ggplot(temp.dat, aes(x = Year, y = Capex, color = State, group = State)) + geom_line() + # Add labels at the end of the line geom_text(data = filter(temp.dat, Year == max(Year)), aes(label = State), hjust = 0, nudge_x = 0.1) + # Allow labels to bleed past the canvas boundaries coord_cartesian(clip = 'off') + # Remove legend & adjust margins to give more space for labels # Remember, the margins are t-r-b-l theme(legend.position = 'none', plot.margin = margin(0.1, 2.6, 0.1, 0.1, "cm"))
quelle
data = filter(temp.dat, Year == max(Year))
innerhalb desgeom_text()
Anrufs verwendet. In Ihrem Fall könnten Sie den Filter auf änderndata = filter(temp.dat, Year == 2008, State = "WA")
, wodurch Sie nur die Bezeichnung "WA" an der x-Position von 2008 erhalten, und Sie könnten die y-Position anpassen, indem Sie dennudge_y
Parameter ingeom_text()
Ich bin auf diese Frage gekommen, um eine angepasste Linie (z. B.
loess()
) am letzten angepassten Punkt und nicht am letzten Datenpunkt direkt zu kennzeichnen . Ich habe schließlich einen Ansatz ausgearbeitet, der größtenteils auf Tidyverse basiert. Es sollte auch für die lineare Regression mit ein paar Mods funktionieren, also lasse ich ihn hier für die Nachwelt.library(tidyverse) temp.dat$Year <- as.numeric(temp.dat$Year) temp.dat$State <- as.character(temp.dat$State) #example of loess for multiple models #https://stackoverflow.com/a/55127487/4927395 models <- temp.dat %>% tidyr::nest(-State) %>% dplyr::mutate( # Perform loess calculation on each CpG group m = purrr::map(data, loess, formula = Capex ~ Year, span = .75), # Retrieve the fitted values from each model fitted = purrr::map(m, `[[`, "fitted") ) # Apply fitted y's as a new column results <- models %>% dplyr::select(-m) %>% tidyr::unnest() #find final x values for each group my_last_points <- results %>% group_by(State) %>% summarise(Year = max(Year, na.rm=TRUE)) #Join dataframe of predictions to group labels my_last_points$pred_y <- left_join(my_last_points, results) # Plot with loess line for each group ggplot(results, aes(x = Year, y = Capex, group = State, colour = State)) + geom_line(alpha = I(7/10), color="grey", show.legend=F) + #stat_smooth(size=2, span=0.3, se=F, show_guide=F) geom_point(size=1) + geom_smooth(se=FALSE)+ geom_text(data = my_last_points, aes(x=Year+0.5, y=pred_y$fitted, label = State))
quelle