This question already has an answer here:
Setting individual y axis limits with facet wrap NOT with scales free_y
(1 answer)
Closed 4 years ago.
I'm trying to create a facet_wrap() where the unit of measure remains identical across the different plots, while allowing to slide across the y axis.
To clearify with I mean, I have created a dataset df:
library(tidyverse)
df <- tibble(
Year = c(2010,2011,2012,2010,2011,2012),
Category=c("A","A","A","B","B","B"),
Value=c(1.50, 1.70, 1.60, 4.50, 4.60, 4.55)
)
with df, we can create the following plot using facet_wrap:
ggplot(data = df, aes(x=Year, y=Value)) + geom_line() + facet_wrap(.~ Category)
Plot 1
To clarify the differences between both plots, one can use scale = "free_y":
ggplot(data = df, aes(x=Year, y=Value)) + geom_line()
+ facet_wrap(.~ Category, scale="free_y")
Plot 2
Although it's more clear, the scale on the y-axis in plot A isequal to 0.025, while being 0.0125 in B. This could be misleading to someone who's comparing A & B next to each other.
So my question right now is to know whether there exist an elegant way of plotting something like the graph below (with y-scale = 0.025) without having to plot two seperate plots into a grid?
Thanks
Desired result:
Code for the grid:
# Grid
## Plot A
df_A <- df %>%
filter(Category == "A")
plot_A <- ggplot(data = df_A, aes(x=Year, y=Value)) + geom_line() + coord_cartesian(ylim = c(1.5,1.7)) + ggtitle("A")
## Plot B
df_B <- df %>%
filter(Category == "B")
plot_B <- ggplot(data = df_B, aes(x=Year, y=Value)) + geom_line() + coord_cartesian(ylim = c(4.4,4.6)) + ggtitle("B")
grid.arrange(plot_A, plot_B, nrow=1)
Based on the info at Setting individual y axis limits with facet wrap NOT with scales free_y you can you use geom_blank() and manually specified y-limits by Category:
# df from above code
df2 <- tibble(
Category = c("A", "B"),
y_min = c(1.5, 4.4),
y_max = c(1.7, 4.6)
)
df <- full_join(df, df2, by = "Category")
ggplot(data = df, aes(x=Year, y=Value)) + geom_line() +
facet_wrap(.~ Category, scales = "free_y") +
geom_blank(aes(y = y_min)) +
geom_blank(aes(y = y_max))
I plot a heatmap using geom_tile (ggplot2):
library("reshape2")
library("ggplot2")
x <- matrix(1:12, nrow=3)
rownames(x) <- LETTERS[1:3]
colnames(x) <- letters[1:4]
x_melted <- melt(x)
x_melted$group1 <- rep(c("T1","T2"), each=6)
ggplot(x_melted, aes(x = Var1, y = Var2)) + geom_tile(aes(fill = value))
But I need add a gap according to group1 in x_melted so that a gap was produced between the first two rows and the last two rows. How could this be added?
One way would be to use facets -
x_melted$group1 = factor(x_melted$group1, levels = c("T2", "T1"))
ggplot(x_melted, aes(x = Var1, y = Var2)) +
geom_tile(aes(fill = value)) +
facet_grid(group1 ~ ., scales = "free_y")
How can I use geom_segment to draw lines on plot, after the data have been melted with reshape2?
# Tiny dataset
facet_group <- c("facet1", "facet1", "facet2", "facet2")
time_group <- c("before", "after", "before", "after")
variable1 <- c(1,5,4,7)
variable2 <- c(2,4,5,8)
variable3 <- c(4,5,6,7)
data <- data.frame(facet_group, time_group, variable1, variable2, variable3)
# Melt data
library(reshape2)
data_melt <- melt(data, id.vars = c("facet_group", "time_group"))
Plot the data:
# Plot 1
library(ggplot2)
ggplot(data_melt, aes(x=variable, y=value, group = time_group)) +
geom_point(aes(color = time_group))
Add faceting:
# Plot 2
ggplot(data_melt, aes(x=variable, y=value, group = time_group)) +
geom_point(aes(color = time_group)) +
facet_grid(facet_group ~ .)
I want to draw a segments from the "before" point to the "after" point for each variable. (see mock up image). How can I do this? I tried some things with geom_segment but I kept having errors. Will casting the data into a new data frame help?? Thanks!
data_cast <- dcast(data_melt, variable + facet_group ~ time_group)
Final "ideal" plot:
You were definitely on the right track with the casted data. Give this a shot:
ggplot(data_melt, aes(x=variable, y=value)) +
geom_point(aes(color = time_group)) +
facet_grid(facet_group ~ .) +
geom_segment(data = data_cast, aes(x = variable, xend = variable,
y = before, yend = after),
arrow = arrow(),
colour = "#FF3EFF",
size = 1.25)
This question already has an answer here:
How to create side-by-side bar charts (for multiple series) with ggplot?
(1 answer)
Closed 5 years ago.
I want to create a barplot using ggplot in R studio using two variables side by side. I tried following other people suggestions I found online, but I cant get it to work.
Here's the data I'm using:
x <- c(5,17,31,9,17,10,30,28,16,29,14,34)
y <- c(1,2,3,4,5,6,7,8,9,10,11,12)
day <- c(1,2,3,4,5,6,7,8,9,10,11,12)
So, what I'm trying to do is have days on the x-axis and side by side barplots of x and y (with x & y being colored) corresponding to the day number.
First thing i did was make a data frame :
df1 <- data.frame(x,y,day)
and then I tried:
ggplot(df1, aes(x = day, y = x,y)) + geom_bar(stat = "identity",color = x, width = 1, position="dodge")
But I just can't get it to work properly. Any suggestions as to how I'd achieve this?
You have the right idea, I think the melt() function from the reshape2 package is what you're looking for.
library(ggplot2)
library(reshape2)
x <- c(5,17,31,9,17,10,30,28,16,29,14,34)
y <- c(1,2,3,4,5,6,7,8,9,10,11,12)
day <- c(1,2,3,4,5,6,7,8,9,10,11,12)
df1 <- data.frame(x, y, day)
df2 <- melt(df1, id.vars='day')
head(df2)
ggplot(df2, aes(x=day, y=value, fill=variable)) +
geom_bar(stat='identity', position='dodge')
EDIT
I think the pivot_longer() function from the tidyverse tidyr package might now be the better way to handle these types of data manipulations. It gives quite a bit more control than melt() and there's also a pivot_wider() function as well to do the opposite.
library(ggplot2)
library(tidyr)
x <- c(5,17,31,9,17,10,30,28,16,29,14,34)
y <- c(1,2,3,4,5,6,7,8,9,10,11,12)
day <- c(1,2,3,4,5,6,7,8,9,10,11,12)
df1 <- data.frame(x, y, day)
df2 <- tidyr::pivot_longer(df1, cols=c('x', 'y'), names_to='variable',
values_to="value")
head(df2)
ggplot(df2, aes(x=day, y=value, fill=variable)) +
geom_bar(stat='identity', position='dodge')
Or you could use facet_wrap to produce two plots:
library("ggplot2")
library("reshape")
x <- c(5,17,31,9,17,10,30,28,16,29,14,34)
y <- c(1,2,3,4,5,6,7,8,9,10,11,12)
day <- c(1,2,3,4,5,6,7,8,9,10,11,12)
df1 <- data.frame(x,y,day)
df2 <- reshape::melt(df1, id = c("day"))
ggplot(data = df2, aes(x = day, y = value, fill = variable)) + geom_bar(stat = "identity")+ facet_wrap(~ variable) + scale_x_continuous(breaks=seq(1,12,2))
If you want the bars with color according to the day use fill = day:
ggplot(data = df2, aes(x = day, y = value, fill = day)) + geom_bar(stat = "identity") + facet_wrap(~ variable) + scale_x_continuous(breaks=seq(1,12,2))
Who can tell me why ggplot can't give me grouped bars?
ggplot(df, aes(x = factor(labels), y = srednia, dodge=factor(group))) +
labs(title = gen, size=3)+ ylab("Fold change")+ xlab("Linnia komórkowa") +
geom_bar(aes(fill=factor(group)),stat="identity",position ="dodge") +
geom_errorbar(aes(ymin=minus, ymax=plus))
Grouped bars I means something like this (paint art):
Thank you in advance!
I guess you can achieve this by changing the scale for the x axis. Here's a reproducible example and a possible solution.
# packages
require(plyr)
require(ggplot2)
# generate data
set.seed(123)
df <- data.frame(labels=LETTERS[1:6],
group=rep(1:3, each=2),
srednia=runif(6))
# limits for x axis
mylims <- head(unlist(dlply(df, .(group), function(x) c(levels(factor(x$labels)), "space"))), -1)
# additional space between groups
ggplot(df, aes(x = factor(labels), y = srednia, dodge=factor(group))) +
geom_bar(aes(fill=factor(group)),stat="identity") +
scale_x_discrete(limits=mylims, breaks=levels(factor(df$labels)))
# removing space within group
ggplot(df, aes(x = factor(labels), y = srednia, dodge=factor(group))) +
geom_bar(aes(fill=factor(group)),stat="identity", width=1) +
scale_x_discrete(limits=mylims, breaks=levels(factor(df$labels)))