ggplot remove the redundant x axis values - r

library(ggplot2)
set.seed(2)
a = sort(rep(c("A","B"),6))
b = c(rep(1:3,2),rep(4:6,2))
cc = rnorm(length(a))
d = rep(sort(rep(1:2,3)),2)
df = data.frame(a,b,cc,d)
print(df)
ggplot(df, aes(x = as.factor(b), y = cc, fill = as.factor(d))) +
geom_bar(stat = "identity", position = "dodge") +
facet_wrap(~a)
In the following plot:
How do I get rid of the redundant x-axis values for each of the factors of a i.e. "A" & "B".
I mean the 4:6 are not required for "A" and similarly 1:3 for "B".
What is the tweak I need to do?

facet_wrap and facet_grid both have a scales argument that let you define which of the x and/ or y scales should be free or fixed.
In your case, you want the x dimensions to be free to be different in both facets, therefore
ggplot(df, aes(x = as.factor(b), y = cc, fill = as.factor(d))) +
geom_bar(stat = "identity", position = "dodge") +
facet_wrap(~ a, scales = 'free_x')

Related

change y axis scale in ggplot

I'm trying to replicate a plot drawn by graphpad in r
but I have a problem changing the y axis
here is an example data and my plot codes:
library(ggplot2)
data <- data.frame(names = rep(factor(LETTERS[1:3])),
values = c(0.001, 0.02 ,0.95),
group = rep("A",3))
ggplot(data,
aes(x = group,
y = values,
fill = names)) + geom_bar(stat = "identity", position='stack') +
scale_y_continuous(breaks = c(0.001,0.01,0.1,1), labels=c(0.001,0.01,0.1,1))
the result of my code is on top but I want to plot it like the image on the bottom.
You can convert the values to their logs, then add a constant that makes all the log values greater than 0. Then re-label the axis appropriately:
data2 <- data %>%
mutate(logvalues = log10(values) - min(log10(0.0001)))
ggplot(data2[order(-data2$logvalues),],
aes(x = group, y = logvalues, fill = names)) +
geom_col(position = 'identity') +
scale_y_continuous(breaks = 0:4, labels = ~ 10^(.x-4))

geom_bar with x and fill aesthetics by one factor and dodge by a second

I have this data.frame:
df <- data.frame(id = c("A","A","B","B","C","C"),
age = rep(c("young", "old"), 3),
value = c(20,15,7,5,2,6))
I'd like to plot it using ggplot2's geom_bar such that the bars are first separated (dodged) by age (but with no gaps between them) and then separated by id (along the x axis, with gaps), and are colored by id.
I'm only familiar with setting either the aes(x) argument to id and the fill argument to age:
ggplot(df, aes(x = id, y = value)) +
geom_bar(aes(fill = age), position = "dodge", stat = "identity") +
theme_minimal()
Or the opposite - the aes(x) argument to age and the fill argument to id:
ggplot(df, aes(x = age, y = value)) +
geom_bar(aes(fill = id), position = "dodge", stat = "identity") +
theme_minimal()
But what I want is the plot to look like the first one above but only filled by id rather than by age.
There's probably a combination position and/or statvalues that get that. Any idea?
You may use the group argument in aes:
ggplot(df, aes(x = id, y = value)) +
geom_bar(aes(group = age, fill = id), position = "dodge", stat = "identity") +
theme_minimal()

overlapping line and bar charts at the dame time with ggplot

Would like to overlap a line chart over a bar chart with ggplot.
Say, V1, V2 are the data for the bar charts, and V3 shall be presented as line.
How can I complete the subset and different geom at the same time?
library(data.table)
library(ggplot2)
set.seed(100)
dat <- data.frame(Axis=letters[1:10],V1=1:10, V2=runif(10, 1,10), V3=10:1)
dat <-melt(data,id.var="Axis",measure.var=c("V1","V2","V3"))
Would it be like this?
ggplot(dat, aes(x=Axis)) +
geom_bar(stat="identity", aes(, y= value[------]))+ # V1, V2 for bars
geom_line(aes(y=value[-----)) # V3 for line
I tried making the subset of V1, V2, and make a bar chart, but can't insent V3 as a line on the chart.
Many thanks
Thanks to #dash2, I slightly changed his code, and make it looks clearer.
ggplot(dat, aes(x = Axis)) +
geom_col(aes(y = V1), fill = "darkred", alpha = .5, width=0.4) +
geom_col(aes(y = V2), fill = "blue", alpha = .5,
position = position_nudge(x = 0.4),width=0.4) +
geom_line(aes(y = V3, group = NA))
Simplest, no melting.
ggplot(data, aes(x = Axis)) +
geom_col(aes(y = V1), fill = "darkred", alpha = .5) +
geom_col(aes(y = V2), fill = "blue", alpha = .5,
position = position_nudge(x = 0.2)) +
geom_line(aes(y = V3, group = NA))
Add aesthetics to taste.
The group argument is necessary. I think that discrete scales (like the x axis here) automatically group their values, leaving you with groups of 1 and no lines being drawn... consistent, but unintuitive.
No need to melt your data, just simply add different aesthetics to each geom:
data <- data.frame(Axis=letters[1:10], V1=1:10, V2=runif(10, 1,10), V3=10:1)
ggplot(data, aes(x = V1)) +
geom_col(aes(y = V2)) +
geom_line(aes(y = V3))
How about this
library(data.table)
library(ggplot2)
set.seed(100)
data <- tibble(Axis=letters[1:10],V1=1:10, V2=runif(10, 1,10), V3=10:1)
data <-melt(data,id.var="Axis",measure.var=c("V1","V2","V3"))
glimpse(data)
ggplot(data, aes(x=Axis, y= data$value)) +
geom_bar(aes(fill = variable), stat="identity")
Another option could be with melt data as:
library(data.table)
library(ggplot2)
set.seed(100)
data <- data.frame(Axis=letters[1:10],V1=1:10, V2=runif(10, 1,10), V3=10:1)
data <-melt(data,id.var="Axis",measure.var=c("V1","V2","V3"))
library(dplyr)
ggplot() +
geom_bar(data=filter(data, variable %in% c("V1", "V2")),
aes(x = Axis, y = value, fill=variable), stat ="identity", position="dodge") +
geom_line(data=filter(data, variable == "V3"),
aes(x = Axis, y = value, colour = variable, group=variable))

ggplot axis custom order with duplicate labels

set.seed(357)
x <- data.frame(name = sample(letters, 10), val = runif(10), stringsAsFactors = F)
x[c(2,6),"name"] <- c("k","k")
ggplot(x, aes(x = name, y = val)) + theme_bw() + geom_bar(stat = "identity")
How can I plot the axis in the same order as x$name? (Yes, the k is duplicate, I want that to show up in the plot like this axis: c k g f o k s v t q)
In the past I used to do:
x$name <- factor(x$name, levels = x$name[order(x$val)], ordered = T)
wich doesn't work any more thanks to:
http://r.789695.n4.nabble.com/factors-with-non-unique-quot-duplicated-quot-levels-have-been-deprecated-since-2009-are-more-depreca-td4721481.html
This is no duplicate of: ggplot: order of factors with duplicate levels
His data structure is completely different.
Also, I have tried setting limits in x_scale_discrete. Doesn't work.
Try this...
x$name2 <- 1:nrow(x)
ggplot(x, aes(x = factor(name2), y = val)) + theme_bw() + geom_bar(stat = "identity") +
scale_x_discrete(labels=x$name)
Actually, simply add the following setting xlab(x$name)
ggplot(x, aes(x = name, y = val)) + theme_bw() + geom_bar(stat = "identity") + xlab(x$name)

plot only a select few facets in facet_grid

I was looking for a way to plot using facet_grid in ggplot2 that only displays just a few select facets. say I have the following plot:
Been looking for a quick way to, for instance, just plot facets 1 and 3.
#data
y<-1:12
x<-c(1,2,3,1,2,3,1,2,3,1,2,3)
z<-c("a","a","a","b","b","b","a","a","a","b","b","b")
df<-as.data.frame(cbind(x,y,z))
#plot
a <- ggplot(df, aes(x = z, y = y,
fill = z))
b <- a + geom_bar(stat = "identity", position = "dodge")
c <- b + facet_grid(. ~ x, scale = "free_y")
c
Obviously I figured out how to just chop up my data first but this must of course be possible to allocate in ggplot2 Even just a nudge would be most welcome.
Use subset in your ggplot call.
plot_1 = ggplot(subset(df, x %in% c(1, 2)), aes(x=z, y=y, fill=z)) +
geom_bar(stat = "identity", position = "dodge") +
facet_grid(. ~ x, scale = "free_y")
Would this be okay,
a <- ggplot(subset(df, x != 2), aes(x = z, y = y, fill = z))
b <- a + geom_bar(stat = "identity", position = "dodge")
c <- b + facet_grid(. ~ x, scale = "free_y")
c

Resources