Related
I'm making a scatterplot and want to label several points with the same label.
data.frame(label=rep(c("a","b","c"),2), x=rep(c(1:3),2), y=(5,4,7,2,6,9))
As you can see, the labels occur twice each at the same x values, only y differs. I want both [1,5] and [1,2] to be labeled using a single "a", not one "a" for each coordinate.
I'm using R, ggplot2 and ggrepel.
This can work:
dat <- data.frame(label=rep(c("a","b","c"),2), x=rep(c(1:3),2), y=c(5,4,7,2,6,9))
ggplot() + geom_point(data=dat, aes(x=x, y=y)) + geom_text(data=dat[duplicated(dat$label),], aes(x=x, y=y, label=label))
I think this is what you want.
I am using the dplyr or tidyverse package.
library(tidyverse)
Dataset
dat1 <- data.frame(label=rep(c("a","b","c"),2), x=rep(c(1:3),2), y=c(5,4,7,2,6,9))
Creating a dataset for the labels. This creates a label dataset which will pick a labeling point at midpoint Y for a given X.
lab1 <- dat1 %>% group_by(label) %>% mutate(x = x, y = mean(y))
This creates the plot using the original dataset for the points and the label dataset for the labels.
ggplot() +
geom_point(data=dat1, aes(x=x, y=y)) +
geom_text(data=lab1, aes(x=x, y=y, label=label), size = 5) +
theme_grey()
The above actually plots the labels twice on top of each other, but you can't notice. If you really just wanted it once, then you could do the following and update the previous code with lab2. I also changed size so you can see.
lab2 <-unique(lab1)
ggplot() +
geom_point(data=dat1, aes(x=x, y=y)) +
geom_text(data=lab2, aes(x=x, y=y, label=label), size=10) +
theme_grey()
If you wanted the x direction more to the right or higher, you could update your label dataset by adding an offset to your label dataset.
lab1 <- dat1 %>% group_by(label) %>% mutate(x = x+.3, y = mean(y) + .5)
Or you can accomplish the same within geom_text itself using nudge.
ggplot() + geom_point(data=dat1, aes(x=x, y=y)) +
geom_text(data=lab1, aes(x=x, y=y, label=label), size=10, nudge_x = .3, nudge_y = .5) +
theme_grey()
I'm a complete R noob and I'm trying to combine multiple beta distributions into a single ggplot. Here is what I've got so far....
#to create a continuous probability function
x=seq(0,1,.01)
q=dbeta(x,2.2,1.7)
z=dbeta(x,3.3,1.2)
df=data.frame(x,q,z)
t=ggplot(df, aes(x)) + # basic graphical object
geom_line(aes(y=q), colour="red") + # first layer
geom_line(aes(y=z), colour="green")+ # second layer
xlab("X value")+ylab("PDF")+
ggtitle("Beta Probability Distribution Functions")
Where did I go wrong?
Here's an alternate approach to the plotting:
library(tidyr)
library(ggplot2)
set.seed(1492) # reproducible
x <- seq(0, 1, .01)
q <- dbeta(x, 2.2, 1.7)
z <- dbeta(x, 3.3, 1.2)
df <- data.frame(x, q, z)
Make it into a long data frame so we can use some inherent properties of ggplot2 w/r/t aesthetics.
df <- gather(df, func, val, -x)
Now, we can use aesthetic mapping vs hard-coding values and doing multiple geom_line()s.
gg <- ggplot(df, aes(x=x, y=val, group=func))
gg <- gg + geom_line(aes(color=func))
Tighten up the y axis limits a bit
gg <- gg + scale_y_continuous(expand=c(0, 0))
We can actually get a legend now (you could also remove it and manually label the lines with geom_text())
gg <- gg + scale_color_manual(name="Beta params",
values=c("#b2182b", "#4393c3"),
labels=c("α=2.2, β=1.7", "α=3.3, β=1.2"))
Combine multiple label statements into one.
gg <- gg + labs(x="x value", y="PDF",
title="Beta Probability Distribution Functions")
Remove some chart junk.
gg <- gg + theme_bw()
gg <- gg + theme(panel.border=element_blank())
gg <- gg + theme(axis.line=element_line(size=0.15, color="#2b2b2b"))
gg
library(ggplot2)
x<-c(1,2,3,4,5)
a<-c(3,8,4,7,6)
b<-c(2,9,4,8,5)
df1 <- data.frame(x, a, b)
x<-c(1,2,3,4,5)
a<-c(6,5,9,4,1)
b<-c(9,5,8,6,2)
df2 <- data.frame(x, a, b)
df.lst <- list(df1, df2)
plotdata <- function(x) {
ggplot(data = x, aes(x=x, y=a, color="blue")) +
geom_point() +
geom_line()
}
lapply(df.lst, plotdata)
I have a list of data frames and i am trying to plot the same columns on the same ggplot. I tried with the code above but it seems to return only one plot.
There should be 2 ggplots. one with the "a" column data plotted and the other with the "b" column data plotted from both data frames in the list.
i've looked at many examples and it seems that this should work.
They are both plotted. If you are using RStudio, click the back arrow to toggle between the plots. If you want to see them together, do:
library(gridExtra)
do.call(grid.arrange,lapply(df.lst, plotdata))
If you want them on the same plot, it's as simple as:
ggplot(data = df1, aes(x=x, y=a), color="blue") +
geom_point() +
geom_line() +
geom_line(data = df2, aes(x=x, y=a), color="red") +
geom_point(data = df2, aes(x=x, y=a), color="red")
Edit: if you have several of these, you are probably better off combining them into a big data set while keeping the df of origin for use in the aesthetic. Example:
df.lst <- list(df1, df2)
# put an identifier so that you know which table the data came from after rbind
for(i in 1:length(df.lst)){
df.lst[[i]]$df_num <- i
}
big_df <- do.call(rbind,df.lst) # you could also use `rbindlist` from `data.table`
# now use the identifier for the coloring in your plot
ggplot(data = big_df, aes(x=x, y=a, color=as.factor(df_num))) +
geom_point() +
geom_line() + scale_color_discrete(name="which df did I come from?")
#if you wanted to specify the colors for each df, see ?scale_color_manual instead
ggplot changes the order of an axis variable, which I do not want. I know I can change the variable to a factor and specify the levels to get around this, but what if the levels contain duplicate values?
An example is below. The only alternative I can think of is to use reorder(), but I can't get that to preserve the original order of the variable.
require(ggplot2)
season <- c('Sp1', 'Su1', 'Au1', 'Wi1', 'Sp2', 'Su2', 'Au2', 'Wi2', 'Sp3', 'Su3', 'Au3', 'Wi3') # this is the order I want the seasons to appear in
tempa <- rnorm(12, 15)
tempb <- rnorm(12, 20)
df <- data.frame(season=rep(season, 2), temp=c(tempa, tempb), type=c(rep('A',12), rep('B',12)))
# X-axis order wrong:
ggplot(df, aes(x=season, y=temp, colour=type, group=type)) + geom_point() + geom_line()
# X-axis order correct, but warning of duplicate levels in factor
df$season2 <- factor(df$season, levels=df$season)
ggplot(df, aes(x=season2, y=temp, colour=type, group=type)) + geom_point() + geom_line()
Just so this has an answer, this works just fine:
df$season2 <- factor(df$season, levels=unique(df$season))
ggplot(df, aes(x=season2, y=temp, colour=type, group=type)) +
geom_point() +
geom_line()
Is it possible to alter the format of an individual facet plot? For example, using the sample code below, can one change the color of the title or background for the cyl=8 plot?
library(ggplot2)
ggplot(mtcars, aes(x=gear)) +
geom_bar(aes(y=gear), stat="identity", position="dodge") +
facet_wrap(~cyl)
You can modify the ggplot2 grobs, for instance:
library("ggplot2")
d <- ggplot(mtcars, aes(x=gear)) +
geom_bar(aes(y=gear), stat="identity", position="dodge") +
facet_wrap(~cyl)
grob <- ggplotGrob(d)
strip_bg <- grid.ls(getGrob(grob, "strip.background.rect",
grep=TRUE, global=TRUE))$name
panel_bg <- grid.ls(getGrob(grob, "panel.background.rect",
grep=TRUE, global=TRUE))$name
strip_text <- grid.ls(getGrob(grob, "strip.text.x",
grep=TRUE, global=TRUE))$name
grob <- geditGrob(grob, strip_bg[2], gp=gpar(fill="gray60"))
grob <- geditGrob(grob, panel_bg[2], gp=gpar(fill="darkolivegreen2"))
grob <- geditGrob(grob, strip_text[2], gp=gpar(col="white"))
grid.draw(grob)
Update: This should work with ggplot2 0.9.3
grob <- ggplotGrob(d)
elem <- grob$grobs$panel2
panel_bg <- grid.ls(getGrob(elem, "panel.background.rect", grep=TRUE))$name
grob$grobs$panel2 <- editGrob(elem, panel_bg, gp=gpar(fill="darkolivegreen"), grep=TRUE)
elem <- grob$grobs$strip_t.1
strip_bg <- grid.ls(getGrob(elem, "strip.background.rect", grep=TRUE))$name
grob$grobs$strip_t.1 <- editGrob(elem, strip_bg, gp=gpar(fill="gray60"), grep=TRUE)
elem <- grob$grobs$strip_t.1
strip_text <- grid.ls(getGrob(elem, "strip.text.x.text", grep=TRUE))$name
grob$grobs$strip_t.1 <- editGrob(elem, strip_text, gp=gpar(col="white"), grep=TRUE)
grid.draw(grob)
I know this is an old question so the original poster is probably long gone but I still think it is worth answering as a resource to future searchers. The accepted answer from rcs does work, but I found it to be rather unstable and hacky. In the end I decided that a more modest but more stable approach is in order. With this method you can only change the background but that suffices for my purposes and might for others, my approach is to use geom_rect to recolour the background, like so:
highlights <- data.frame(cyl=c(8))
ggplot() +
geom_rect(data=highlights,aes(xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf), fill='red', alpha=0.2) +
geom_bar(data = mtcars, aes(x=gear), position="dodge", fill = 'black') +
facet_wrap(~cyl)
This might help you get a little bit closer to what you want:
mtcars2 = subset(mtcars, cyl != 8)
subs = subset(mtcars, cyl == 8)
require(ggplot2)
ggplot(mtcars2, aes(x=gear)) +
geom_bar(aes(y=gear, fill = 'black'), stat="identity", position="dodge") +
geom_bar(data = subs, aes(x = gear), fill = 'blue', binwidth = 1) +
facet_wrap(~cyl)