I'm trying to make a plot with horizontal boxplots in ggplot2, which you can only do by using coord_flip(). I'm also trying to space the boxplots vertically to group certain sets together. I have read that faceting is recommended for this kind of thing, but this is incompatible with coord_flip(), as we can see here: ggplot2: boxplot with facet_grid and free scale. So I'm wondering if it's possible to use blank levels in order to create blank spaces. Here's what I've managed to do so far:
d <- diamonds
library("ggplot2")
levels(d$cut) <- list(A="Fair", B="Good", "-", C="Very Good", D="Ideal", E="Premium")
p = ggplot(d, aes(x=cut, y=depth))
p +
geom_boxplot(color="black", size=0.2) +
theme_bw() +
scale_x_discrete(breaks = c("A", "B", "-", "C", "D", "E"), drop=FALSE) +
coord_flip()
ph = 2.75
pw = 4
ggsave("plot.png", height=ph, width=pw)
As you can see, if I create a blank level with "-" in it and include it in scale_x_discrete(), then somehow I get a blank row. The problem is I can only add one space. Does anyone have any ideas on how to add spaces between these horizontal box plots?
Here's one way that will let you add more blank levels:
d <- diamonds
levels(d$cut) <- list(A="Fair", B="Good", " "="space1", C="Very Good", D="Ideal", " "="space2", E="Premium")
ggplot(d, aes(x=cut, y=depth)) +
geom_boxplot(color="black", size=0.2) +
theme_bw() +
scale_x_discrete(breaks = c("A", "B", " ", "C", "D", " ", "E"), drop=FALSE) +
coord_flip()
This will leave tick marks on the spacers as well, though:
Removing all ticks is simple by adding:
+ theme(axis.ticks.y = element_line(linetype=0))
But if you want to remove the tick marks only for the spacers, at least one way (I'm sure there others) is to do it with a custom function:
f <- function(x) {
x[!x %in% c("A", "B", "C", "D", "E")] <- NA
x
}
ggplot(d, aes(x=cut, y=depth)) +
geom_boxplot(color="black", size=0.2) +
theme_bw() +
scale_x_discrete(breaks=f, drop=FALSE) +
coord_flip()
Related
I've no idea where to even start with this. I've looked at GGPlot and plotly etc to try and find the right thing but haven't come across anything.
This is as example of my data though
Skill <- c("Tackling", "Shooting", "Technique", "Passing", "Pace", "Stamina")
Grade <- c("A", "C", "C", "B", "A", "B")
data <- data.frame(Skill, Grade)
This is the sort of graph I'd like
I'm a football scout and it would be fantastic to be able to have a graph like that to compare the players we have to the player I'm scouting.
so if the grade is D, it would just show red, if the grade was C it would show red and orange. Etc.
This is quite close to what you want:
Skill <- c("Tackling", "Shooting", "Technique", "Passing", "Pace", "Stamina")
Grade <- c("A", "C", "C", "B", "A", "B")
data <- data.frame(Skill, Grade)
library(ggplot2)
library(dplyr)
data$grade <- factor(data$Grade, levels=c("D","C","B","A"))
data$grade2 <- recode(data$grade, A="B")
data$grade3 <- recode(data$grade2, B="C")
data$grade4 <- recode(data$grade3, C="D")
ggplot(data, aes(x=Skill, y=grade)) +
geom_bar(stat="identity", fill="green",col="black",width=1) +
geom_bar(aes(y=grade2),stat="identity", fill="yellow",col="black",width=1) +
geom_bar(aes(y=grade3),stat="identity", fill="orange",col="black",width=1) +
geom_bar(aes(y=grade4),stat="identity", fill="red",col="black",width=1) +
scale_y_discrete(limits = c("D","C","B","A")) +
coord_polar(start = pi/6) + theme_bw() + theme(axis.text.y = element_blank()) +
theme(axis.ticks = element_blank(), axis.title = element_blank())
How about this
library(ggplot2)
ggplot(data = data, aes(Skill, Grade, fill = Grade)) +
geom_tile() +
coord_polar() +
theme_bw()
To have all levels below the grade coded, you'll need to have all those lower levels within the dataframe, which is in a way redundant. Wouldn't it be?
d = transform(data, gr = as.numeric(factor(data$Grade, c("D", "C", "B", "A"))))
d = do.call(rbind, lapply(split(d, d$Skill), function(x){
foo = with(x, setNames(data.frame(Skill[1], Grade[1], seq(gr)), names(x)))
}))
library(ggplot2)
ggplot(d, aes(Skill, gr, fill = factor(gr, 4:1))) +
geom_col() +
coord_polar()
Let's say, I have data like following example,
dat1 <- data.frame(group = c("a", "a","a", "a", "a", "b", "b", "b","b","b","b","b","c","c","c"),
subgroup = c(paste0("R", rep(1:5)),paste0("R", rep(1:7)),paste0("R", rep(1:3))),
value = c(5,6,0,8,2,3,4,5,2,4,7,0,3,4,0),
pp = c("AT","BT","CT","AA","AT","TT","RT","CC","SE","DN","AA","MM","XT","QQ","HH"))
And, I want to add some cut off as dat1 = dat1[dat1$value > 2, ]. My code
pl <- ggplot(dat1, aes(y = as.character(pp), x = as.factor(subgroup))) +
geom_point( aes(size=as.numeric(value)))+ facet_grid(cols = vars(group), scales="free", space="free")+
ylab("names") +xlab(" ")
pl
enter image description here
But I want to see all scale in each panel. For example in the first panel, there are five values or five scales even if below of cut off or zero I just want to see all five scale. The second panel has 7 scales but after cut off, there should be 6 columns, but I want to see all 7 scales even if it has zero.
How can I modify my code or make as this kind of plot?
We can use the scales and space arguments in facet_grid.
ggplot(dat1, aes(subgroup, pp)) +
geom_point(aes(size = value)) +
facet_grid(cols = vars(group), scales = "free", space = "free")
I want to display data with a horizontal bar chart and facet it by a grouping variable. Since I want a horizontal graph with faceting, I'll use geom_barh from the ggstance package. I have a data set where my observations are divided into a few different types with counts. Something like this:
library(tidyverse)
data <- tibble(observations = c(1:17),
type = c("a", "a", "a", "a",
"b", "b", "b", "b", "b", "b",
"c", "c", "c", "c", "c", "c", "c"),
n = c(30:46))
Here's my problem. When I use facet_wrap, my bars have different widths:
library(ggstance)
ggplot(data, aes(x = n, y = reorder(observations, n))) +
geom_barh(stat = "identity") +
facet_wrap(~ type, ncol = 1, scales = "free_y")
But when I use facet_grid, I can't move the strip to the top because there's no strip.position argument:
ggplot(data, aes(x = n, y = reorder(observations, n))) +
geom_barh(stat = "identity") +
facet_grid(type ~ . , scales = "free_y", space = "free_y")
Is this just one of the quirks of ggplot or is there a way to manipulate this?
I don't think ggplot2 is intended for this purpose, but like many other cases, if you are willing to accept a grob (rather than a ggplot2 object) as the end result, hacking a solution is possible.
The basic idea here is that facet_wrap() allows the strip to be in any position (top / left / right / bottom), while fact_grid() allows the height / width of panels to differ. If we convert the ggplot2 result from each option to a grob object, we can apply the panel heights of option 2 to option 1. Here's how:
Step 1. Create ggplot2 objects based on both facet_wrap() & facet_grid(). Convert them to grob objects. (note: I don't have the ggstance package installed, but the usual geom_col() + coord_flip() should be similar for the purpose of illustrating the concept here...)
p1 <- ggplot(data, aes(y = n, x = reorder(observations, n))) +
geom_col() +
facet_wrap(~ type, ncol = 1, scales = "free_y") +
coord_flip()
g1 <- ggplotGrob(p1)
p2 <- ggplot(data,
aes(y = n, x = reorder(observations, n))) +
geom_col() +
facet_grid(type ~ . , scales = "free_y", space = "free_y") +
coord_flip()
g2 <- ggplotGrob(p2)
Step 2. Get the location of panel rows in both g1 & g2's layouts:
g1.panel.rows <- g1$layout$t[grep("panel", g1$layout$name)] #7 / 12 / 17 in this case
g2.panel.rows <- g2$layout$t[grep("panel", g2$layout$name)] #6 / 8 / 10 in this case
# optional: view the layout & visually check that the above are correct
gtable::gtable_show_layout(g1)
gtable::gtable_show_layout(g2)
# also optional (but recommended): check the current height associated with each panel;
# note that g1 has equal height for each panel, while g2 does not
> g1$heights[g1.panel.rows]
[1] 1null 1null 1null
> g2$heights[g2.panel.rows]
[1] 4.2null 6.2null 7.2null
Step 3. Apply g2's panel heights to g1's panels & view the result.
g1$heights[g1.panel.rows] <- g2$heights[g2.panel.rows]
grid::grid.draw(g1)
I have a dataset, named “data”:
df=ddply(data,c("Treatment","Concentration"),summarise,mean=mean(Inhibition),sd=sd(Inhibition),n=length(Inhibition),se=sd/sqrt(n))
p <- ggplot(df, aes(x=Treatment, y=Inhibition))
p1 <- p + geom_bar(stat="identity", position="dodge") +
geom_errorbar(aes(ymin=Inhibition-se,ymax=Inhibition+se), position="dodge",width=0.2)
and I got the following graph:
I want x-axis to be like the picture below:
How woud I do this??
This is best achieved using a facet within ggplot. As you haven’t included a reusable dataset, I have made one here:
df <- data.frame(Group = c("A", "A", "A", "A", "B"),
SubGroup = c(letters[1:5]),
value = 1:5
)
See below the facet_grid line which has a few additional options specified. You can read more about the added arguments here
library(ggplot2)
ggplot(df, aes(x = SubGroup, value)) +
geom_bar(stat="identity", position="dodge") +
facet_grid(.~Group, scales = "free_x", space = "free", switch = "x") +
theme(strip.placement = "outside")
For your data, you will need to split the drug and dose into two separate columns first, like my example.
I am working on ggplot2, here is my sample data,
type <- c("A", "B", "C", "D", "E","F")
point <- c(3,5,8,6,100,9)
data <- data.frame(type, point)
ggplot(data, aes(x=type, y=point, fill="type")) +
geom_bar(stat="identity") +
geom_text(data=data, aes(label=paste(type,"-",point)))
As you can see, the E bar is too high, so I want to remove y axis from 15-95, so I can see the difference of other lower types.
I know there are some thing like scale free x or y in facet_grid or facet_wrap, anything like these in a simgle plot like mine?
EDIT TO ADD FORMATTING
Does this work for you?
library(scales)
ggplot(data, aes(x=type, y=point, fill="type")) +
geom_bar(stat="identity") +
geom_text(data=data, aes(label=paste(type,"-",point))) +
scale_y_log10(labels = comma)
EDIT 2
OR
If you don't want commas...
ggplot(data, aes(x=type, y=point, fill="type")) +
geom_bar(stat="identity") +
geom_text(data=data, aes(label=paste(type,"-",point))) +
scale_y_log10(labels = format_format(scientific = FALSE))