Plotting geom_bar and geom_point together? - r

data=data.frame(x=rep(0:9, each=2))
ggplot(data, aes(x=factor(x))) + geom_bar(alpha=0.5) +
geom_point(data=data.frame(x=0:10, y=2), aes(x=factor(x), y=y), alpha=0.5)
ggplot(data, aes(x=factor(x))) + geom_bar(alpha=0.5) +
geom_point(data=data.frame(x=0:10, y=2), aes(x=factor(x), y=y), alpha=0.5) +
scale_x_discrete(limits=0:10)
Also, do I have to factor given x is integer so it is discrete already?
Wrong order
Wrong x axis label.

ggplot(data, aes(x=x)) + geom_bar(alpha=0.5) + scale_x_discrete(limits=0:10) +
geom_point(data=data.frame(x=0:10, y=2), aes(x=x, y=y), alpha=0.5)
You can force a discrete scale to get what you want. It is odd how when you mix geom_point() and geom_bar() ggplot starts ordering things in unexpected ways.

Related

Change y axis text in ggplot

I have the following dataset I would like to plot.
library(tidyverse)
df <- data.frame(first=c(40,40,40),second=c(40,80,160),third=c(40,160,640), ID=c("ID1","ID2","ID3")) %>% pivot_longer(cols=-ID)
I am using:
ggplot(df2, aes(x=name, y=value, group=ID)) +
geom_line() +
geom_point(size=4)
Currently, I have:
Is there a way to change the values shown on the y axis:
1:40
1:80
1:160
1:320
1:640
Basically, I am writing a string for the continues numeric values on y
You can set the breaks= and label= parameters to change your y-axis labels
ggplot(df, aes(x=name, y=value, group=ID)) +
geom_line() +
geom_point(size=4) +
scale_y_continuous(breaks=c(40,80,160,320,640), label=function(x) paste0("1:", x))

How to overlay geom_bar and geom_line plots with different number of elements using ggplot2?

Assuming I have two data.frames with different data but in the same range of x-values
a <-data.frame(x=c(1,1,1,2,2,2,3,3,3),
y=c(0.3,0.4,0.3,0.2,0.5,0.3,0.4,0.4,0.2),
z=c("do","re","mi","do","re","mi","do","re","mi"))
b <- data.frame(x=c(1,2,3),y=c(10,15,8))
Both, a and b have the same range of X values (1,2,3) but while a is a data.frame with 9 rows, b is a data.frame with 3 rows.
I use geom_bar in order to plot the distribution of values of a, like this:
ggplot(a, aes(x=x, y=y, fill=z)) +
geom_bar(position="stack",stat="identity") +
ylab("") +
xlab("x")
And I use geom_line to plot b data, like this:
ggplot(b, aes(x=x, y=y)) +
geom_line(stat="identity") +
ylab("") + xlab("x") + ylim(0,15)
Now I would like to overlay this geom_line plot to the previous geom_bar plot. My first try was to do the following:
ggplot(a, aes(x=x, y=y, fill=z)) +
geom_bar(position="stack",stat="identity") +
ylab("") + xlab("x") +
ggplot(b, aes(x=x, y=y)) +
geom_line(stat="identity") +
ylab("") + xlab("x") + ylim(0,15)
With no success.
How can I overlay a geom_line plot to a geom_bar plot?
Try this
p <- ggplot()
p <- p + geom_bar(data = a, aes(x=x, y=y, fill=z), position="stack",stat="identity")
p <- p + geom_line(data = b, aes(x=x, y=y/max(y)), stat="identity")
p
Update:
You can rescale the one y to make them the same. As I don't know the relations between the two ys, I rescaled them by using y/max(y). Does this solve you problem?
Try merging the datasets first, then plotting, like this:
require(ggplot2)
df <- merge(a,b,by="x")
ggplot(df, aes(x=x, y=y.x, fill=z)) +
geom_bar(position="stack",stat="identity") +
geom_line(aes(x=x, y=y.y)) +
ylab("") + xlab("x")
Output:
I edited the sample data to better illustrate the effects, because the y-axis scaling of the original data would not have matched well:
a <-data.frame(x=c(1,1,1,2,2,2,3,3,3),
y=c(0.3,0.4,0.3,0.2,0.5,0.3,0.4,0.4,0.2),
z=c("do","re","mi","do","re","mi","do","re","mi"))
b <- data.frame(x=c(1,2,3),y=c(.4,1,.4))

plotting: color based on the combination of two column levels

How to plot based on the combination of two column levels(here: treatment, replicate)?
set.seed(0)
x <- rep(1:10, 4)
y <- sample(c(rep(1:10, 2)+rnorm(20)/5, rep(6:15, 2) + rnorm(20)/5))
treatment <- sample(gl(8, 5, 40, labels=letters[1:8]))
replicate <- sample(gl(8, 5, 40))
d <- data.frame(x=x, y=y, treatment=treatment, replicate=replicate)
plots: color based on single column levels
ggplot(d, aes(x=x, y=y, colour=treatment)) + geom_point()
ggplot(d, aes(x=x, y=y, colour=replicate)) + geom_point()
The combination of two column levels would be a-1, a-2, a-3, ... h-6, h-7, h-8.
64 colours will be uninterpretable. How about point labels instead:
ggplot(d, aes(x=x, y=y, colour=treatment)) +
geom_text(aes(label=paste0(treatment, replicate)), size=3, show.legend=FALSE) +
theme_classic()
Or, if you're trying to spot differences in patterns for different treatments, maybe faceting would help:
ggplot(d, aes(x=x, y=y, colour=treatment)) +
geom_text(aes(label=paste0(treatment, replicate)), size=3, show.legend=FALSE) +
facet_wrap(~ treatment, ncol=4) +
scale_x_continuous(expand=c(0,0.7)) +
theme_bw() + theme(panel.grid=element_blank())
But, if you really want a whole bunch of colours...
ggplot(d, aes(x=x, y=y, colour=interaction(treatment,replicate,sep="-",lex.order=TRUE))) +
geom_point() +
labs(colour="Treatment-Replicate") +
theme_classic()
(If you want all potential treatment-replicate combinations to be listed in the legend, regardless of whether they're present in the data, then add + scale_colour_discrete(drop=FALSE) to the plot code.)

ggplot geom_line for specific factor levels

Is there a way to add a line for specific factor levels in ggplot?
this simple example could provide a base to explain what I'm trying to say. In this case I'd like to avoid plotting the last level.
ggplot(BOD, aes(x=factor(Time), y=demand, group=1)) + geom_line() + geom_point()
You can just simply create a new variable with an NA-value for Time == 7:
BOD$demand2[BOD$Time<7] <- BOD$demand[BOD$Time<7]
and then plot:
ggplot(BOD, aes(x=factor(Time), y=demand2, group=1)) +
geom_line() +
geom_point() +
theme_classic()
You could also do it on the fly by utilizing the functionality of the data.table-package:
library(data.table)
ggplot(data = as.data.table(BOD)[Time==7, demand := NA],
aes(x=factor(Time), y=demand, group=1)) +
geom_line() +
geom_point() +
theme_classic()
To answer your comment, you could include the point at 7 as follows:
ggplot(BOD, aes(x=factor(Time), y=demand2, group=1)) +
geom_line() +
geom_point(aes(x=factor(Time), y=demand)) +
theme_classic()

How to get ggplot aes(col=var) effect without changing line color

How can I make this plot:
library(ggplot2)
library(data.table)
dt <- data.table(x=1990:2001, y=rnorm(5), z=c("a","b","c"))
ggplot(dt, aes(x=x, y=y, col=z)) +
geom_line()
execpt with the lines all in the same color? I don't know whether there is another aes argument to use or something else to do.
This doesn't do anything:
ggplot(dt, aes(x=x, y=y, col=z), col="black") +
geom_line()
And this merges all the lines into one:
ggplot(dt, aes(x=x, y=y, col=z)) +
geom_line(col="black")
If you just want separate lines for every distinct z you can use the group argument
ggplot(dt, aes(x=x, y=y, group=z)) + geom_line()
If you want to give all lines a color, but the same you need to specify it outside of the aesthetics like this
ggplot(dt, aes(x=x, y=y, group=z)) + geom_line(color = "blue")

Resources