For multiple (here: two) value lists I want to
plot values as line or points into one diagram
plot histograms into another diagram and
assign the same color to the respective line plot and histogram plot
I've come up with a combination of two examples using ggplot2, which is still using different colors for line plot and histograms. Also it may be a bit redundant, creating
How can I get the same color for line plot and histogram?
Bonus: How can I shorten the piece of used source code?
my result so far:
Source Code (R):
# input data lists
vals_x <- c(4, 3, 6, 7, 4, 6, 9, 3, 0, 8, 3, 7, 7, 5, 9, 0)
vals_y <- c(6, 6, 4, 8, 0, 3, 7, 3, 1, 8, 2, 1, 2, 3, 6, 5)
# ------------------------------------------------
library(ggplot2)
library(gridExtra)
# prepare data for plotting
df <- rbind( data.frame( fill = "blue", obs = vals_x),
data.frame( fill = "red", obs = vals_y))
test_data <- data.frame(
var0 = vals_x,
var1 = vals_y,
idx = seq(length(vals_x)))
stacked <- with(test_data,
data.frame(value = c(var0, var1),
variable = factor(rep(c("Values x","Values y"),
each = NROW(test_data))),
idx = rep(idx, 2),
fill_col = c( rep("blue", length(vals_x)),
rep("red", length(vals_y)))))
# plot line
p_line <- ggplot(stacked, aes(idx, value, colour = variable)) +
geom_line()
# plot histogram
p_hist <- ggplot( df, aes(x=obs, fill = fill)) +
geom_histogram(binwidth=2, colour="black", position="dodge") +
scale_fill_identity()
# arrange diagrams
grid.arrange( p_line, p_hist, ncol = 2)
The easiest thing to do is
Use the same data set in each ggplot object
Then use scale_*_manual (or some other scale call).
So
## Particularly awful colours
p_hist = ggplot(stacked, aes(x=value, fill=variable)) +
geom_histogram(binwidth=2, colour="black", position="dodge") +
scale_fill_manual(values=c("red", "yellow"))
p_line = ggplot(stacked, aes(idx, value, colour = variable)) +
geom_line() +
scale_colour_manual(values=c("red", "yellow"))
As an aside, I wouldn't use a histogram here; a boxplot or density plot would be much better.
Related
I am trying to plot rectangles in the x-axis for different classes in the y-axis. I want to do this with geom_rect, but I don't want to use y_min and y_max since I want these to be determined by the classes (i.e. factors) I have in my data.
I managed to get the plot I want changing the breaks and the tick labels manually, but I am sure there must be a better way to do this.
Small toy example:
data <- data.frame(x_start = c(0, 2, 4, 6),
x_end = c(1, 3, 5, 7),
y_start = c(0, 0, 2, 2),
y_end = c(1, 1, 3, 3),
info = c("x", "x", "y", "y"))
Original plot:
ggplot(data ,aes(xmin=x_start, xmax=x_end, ymin=y_start, ymax=y_end, fill=info)) + geom_rect()
Plot that I want:
ggplot(data ,aes(xmin=x_start, xmax=x_end, ymin=y_start, ymax=y_end, fill=info)) + geom_rect() +
scale_y_continuous(breaks = c(0.5,2.5), labels = c("x","y"))
library(dplyr)
y_lab <- data %>%
distinct(y_end, y_start, info) %>%
mutate(y_mid = (y_end + y_start)/2)
ggplot(data, aes(xmin=x_start, xmax=x_end, ymin=y_start, ymax=y_end, fill=info)) +
geom_rect() +
scale_y_continuous(breaks = y_lab$y_mid, labels = y_lab$info)
Or using geom_tile:
ggplot(data, aes(x = (x_start + x_end)/2, y = info, fill=info, width = 1)) +
geom_tile()
I'm plotting a graph in R using ggplot2. It's a lined graph with points for every observations, the points represent p-values. Three of them are not significant, and I want these points to show up differently (any other shape/color, doesn't matter). Now I'm not sure how to do this.
I've tried scale_shape_manual(values = c(valueA, valueB, valueC)) and
scale_color_manual, but I don't get any results. No error messages either, just nothing happens.
Can anyone help?
ggplot(data = dataframe) +
geom_line(aes(x=Time, y=Treatment), color="#00AFBB")+
geom_point(aes(x=Time, y=Treatment)) +
scale_y_reverse()+
scale_x_continuous( breaks = c(1, 2, 3, 4, 5, 6,7,8,9,10,11,12,13,14,15,16,17,18,19,20))
Thanks!
--
Edit: here a reproducible sample (I hope it works?):
A <- c(1,2,3,4,5)
B <- c(1,2,3,4,5)
df <- data.frame(cbind(A, B))
Here's an example, hopefully helpful. I use scale_color_identity and scale_shape_identity because my data (in this case created through the if_else statements) specifies the literal color/shape I want to use.
Time <- c(1,2,3,4,5)
Treatment <- c(1,2,3,4,5)
df <- data.frame(Time = 1:5, Treatment = 1:5)
ggplot(data = df) +
geom_line(aes(x=Time, y=Treatment), color = "#00AFBB") +
geom_point(aes(x=Time, y=Treatment,
shape = if_else(Treatment < 5, 18, 1),
color = if_else(Treatment < 5, "#00AFBB", "black")), size = 4) +
scale_y_reverse()+
scale_x_continuous( breaks = 1:20) +
scale_color_identity() +
scale_shape_identity()
install.packages("ggplot2")
library(ggplot2)
vector1 <- c(1, 4, 5, 6, 2, 4, 5, 8)
vector2 <- c(1, 2, 3, 4, 5, 6, 7, 8)
dataframe <- data.frame(vector1, vector2)
dataframe$vector2 <- as.factor(dataframe$vector2)
plot <- ggplot(dataframe, aes(vector2, vector1))
plot +geom_bar(stat = "identity")
I would like to make a text box somewhere in the bar chart window that shows values of 1-8 corresponding to levels of a factor. If I give the levels character-based names, it clutters the x-axis, and I don't want that. So I figured a legend that corresponds numbers to the levels would be great alternative. e.g. Ideally, each level of a factor is descending as a row, like a legend.
1 - slippery roads
2 - dry roads
3 - something creative
etc.
Ok here is another approach. There might be easier ones.
We use the guide for fill, remove the legend keys and overlay a second set of bars.
ggplot() + geom_col(data = dataframe, aes(vector2, vector1, fill = vector2)) +
geom_col(data = dataframe, mapping = aes(vector2, vector1)) +
scale_fill_discrete(name = "", labels = paste0(1:8, " roads")) +
theme(legend.position = c(.3, .8),
legend.key = element_blank(),
legend.background = element_blank()) +
guides(fill=guide_legend(override.aes=list(fill = NA),
keywidth = 0, keyheight = 0, nrow = 2))
I'm trying to get a heat map using three variables: Discrete (x,y) for coordinates and a z which is a weight. I want bins/tiles to have colors depending on the sum. I get a decent result as follows:
x = c(8, 9, 10, 11, 12, 12)
y = c(3, 4, 5, 6, 6, 6)
z = c(1, 4, 2, 2, 8, 8)
dd <- data.frame(x,y,z)
p <- ggplot(dd, aes(x=x,y=y,weight=z)) +
stat_bin2d(bins=c(5,4))
p
It's not exactly what I want, since the bins are squeezed into a space that's not really big enough and they're not centered onto the coordinates.
I discovered geom_tile which seems to be the way to go, except I can't figure out how to get the fill color to be based on the weight (summed z for each bin) as it worked with stat_bin2d. The following uses a fill based on z but isn't the sum. You can see the difference in the value of the (12,6) bin which is 8 rather than 16.
p <- ggplot(dd, aes(x=x,y=y,weight=z)) +
geom_tile(aes(fill=z)) +
scale_fill_gradient(low = "black", high = "steelblue")
What am I missing?
Using factors will center the tiles with stat_bin_2d:
p <- ggplot(dd, aes(x=as.factor(x),y=as.factor(y),weight=z)) +
stat_bin2d()
p
I would preprocess the data to calculate the sums
library(ggplot2)
library(dplyr)
dd %>%
group_by(x, y) %>%
summarise(z = sum(z)) %>%
ggplot(aes(x=x,y=y,fill=z)) +
geom_tile() +
scale_fill_gradient(low = "black", high = "steelblue")
I'm trying to create a facet_wrap plot that compares four separate lines to a common fifth line; the goal is to have this fifth line appearing on all four of the other facet_wrap plots.
Here's my minimal code:
library(ggplot2)
x = c( 1, 3, 1, 3, 2, 4, 2, 4)
y = c( 1, 3, 2, 4, 1, 3, 2, 4)
type = c("A","A","B","B","C","C","D","D")
data = data.frame(x,y,type)
x = c( 4, 1)
y = c( 1, 4)
type = c("E","E")
line = data.frame(x,y,type)
ggplot(data, aes(x,y)) + geom_line() + facet_wrap(~type) +
geom_line(data = line, aes(x,y))
I was hoping that adding the fifth line as an independent data.frame would allow me to do this, but it just adds it as a fifth facet, as in the following image:
I want the "E" facet to show up on all of the other plots. Any thoughts? I know that geom_vline, geom_hline, and geom_abline will all appear on all of the facets, but I'm not sure what makes them unique.
You have specified type='E' in your line data.frame. If you want to have this line on type A,B,C,D, then create a data.frame with the types on which you want the line to display
xl = c( 4, 1)
yl = c( 1, 4)
type =rep(LETTERS[1:4], each=2)
line2 = data.frame(x=xl,y=yl,type)
ggplot(data, aes(x,y)) + geom_line() + facet_wrap(~type) +
geom_line(data = line2)
You could also use annotate, which means you don't specify a data.frame, but pass the x and y values directly
ggplot(data, aes(x,y)) + geom_line() + facet_wrap(~type) +
annotate(geom='line', x=xl,y=yl)
Both create
You could also use geom_abline(...) as follows:
x <- c( 1, 3, 1, 3, 2, 4, 2, 4)
y <- c( 1, 3, 2, 4, 1, 3, 2, 4)
type <- c("A","A","B","B","C","C","D","D")
data <- data.frame(x,y,type)
int <- c(5,5,5,5)
slope <- c(-1,-1,-1,-1)
type <- c("A","B","C","D")
ref <- data.frame(int, slope, type)
ggplot(data, aes(x,y)) + geom_line() + facet_wrap(~type, scales="free") +
geom_abline(data = ref, aes(intercept=int, slope=slope), color="red", size=2)
Which produces this: