I have the following data.frame:
x = data.frame(category=c(1,1,1,1,2,2,2,2), value=c(1,2,1,1,2,2,2,1));
x$category = as.factor(x$category);
x$value = as.factor(x$value);
and I have created a faceted bar chart with ggplot2.
ggplot(x, aes(value, fill=category)) + geom_bar() + facet_wrap(~category);
However, I would like to have a pie chart that shows the fraction values (based on the totals for each category). The diagram should then show one pie chart for each category and two fractions inside each pie chart, one for each value factor. The real data has up to 6 categories and I have a few 1000 data sets). Is there a generic way to do that?
One way is to calculate the percentage/ratio beforehand and then use it to get the position of the text label. See also how to put percentage label in ggplot when geom_text is not suitable?
# Your data
y = data.frame(category=c(1,1,1,1,2,2,2,2), value=c(2,2,1,1,2,2,2,1))
# get counts and melt it
data.m = melt(table(y))
names(data.m)[3] = "count"
# calculate percentage:
m1 = ddply(data.m, .(category), summarize, ratio=count/sum(count))
#order data frame (needed to comply with percentage column):
m2 = data.m[order(data.m$category),]
# combine them:
mydf = data.frame(m2,ratio=m1$ratio)
# get positions of percentage labels:
mydf = ddply(mydf, .(category), transform, position = cumsum(count) - 0.5*count)
# create bar plot
pie = ggplot(mydf, aes(x = factor(1), y = count, fill = as.factor(value))) +
geom_bar(stat = "identity", width = 1) +
facet_wrap(~category)
# make a pie
pie = pie + coord_polar(theta = "y")
# add labels
pie + geom_text(aes(label = sprintf("%1.2f%%", 100*ratio), y = position))
Related
I'm generating a stacked density plot:
ggplot(data=tydy_rawdata, aes(x=timepoint, y=tpm, group=fct_inorder(names),
fill=fct_inorder(names))) +
geom_density(position="fill",
stat="identity") +
scale_fill_manual(values = rev(mycolors))
plot :
I would like to add label on each curve (or at least the top 3 or 4) basing on the "names" displayed on the right.
I'm trying adding geom_text but the result is this :
gplot(data=tydy_rawdata, aes(x=timepoint, y=tpm, group=fct_inorder(names),
fill=fct_inorder(names))) +
geom_density(position="fill",
stat="identity") +
geom_text(aes(label=names)) +
scale_fill_manual(values = rev(mycolors))
plot :
Are there some way to do it?
First, your chart is a stacked area chart, i.e. geom_density with stat="identity" is equal to geom_area. Second, when adding labels via geom_text you have to take account of the position argument. As you use position="fill" for your density/area chart you also have to do the same for geom_text.
As you provided no example data I created my own to make your issue reproducible:
library(ggplot2)
library(forcats)
set.seed(123)
tydy_rawdata <- data.frame(
names = rep(LETTERS[1:10], each = 6),
timepoint = factor(seq(6)),
tpm = runif(6 * 10, 0, 80)
)
ggplot(data = tydy_rawdata, aes(
x = timepoint, y = tpm,
group = fct_inorder(names), fill = fct_inorder(names)
)) +
geom_area(
position = "fill",
color = "black"
) +
geom_text(aes(label = names), position = "fill")
I'm trying to draw a grouped bar plot in r
Here is my code:
xtable <- xtabs(~ view + grade, data=hs)
xtable
barplot(xtable, beside = T, legend.text = T)
library(reshape2)
data.m <- melt(xtable, id.vars='view')
data.m
# plot
ggplot(data.m, aes(grade, value)) + geom_bar(aes(fill = view),
width = 0.4, position = "dodge", stat="identity") +
theme(legend.position="top", legend.title =
element_blank(),axis.title.x=element_blank(),
axis.title.y=element_blank())
View and grade are two properties of homes sold. Grade is a value between 0 to 13 showing the rank of a home, and view is 0 to 4 showing how good is the view of the home.
The usual barplot command in r works oaky. However, I liked a ggplot for it.
I followed the answer of similar questions, but I get a stacked bar instead of a grouped one. Also, how can I generate a segmented bar plot and spine plot using the same data?
Your code considers view as continuous, where it is not. Convert it to factor.
library(ggplot2)
library(reshape2)
hs <- read.csv(file = file.choose())
xtable <- xtabs(formula = (~ view + grade),
data = hs)
data.m <- melt(data = xtable,
id.vars='view')
ggplot(data = data.m,
mapping = aes(x = grade,
y = value)) +
geom_bar(mapping = aes(fill = factor(x = view)),
position = "dodge",
stat="identity")
This generates the following, which you can modify later to make it look nicer.
I have the following data:
CT VT TT
A* 5.923076923 6.529411765 5.305555556
Not A* 5.555555556 6.434782609 5.352941176
I want to make a grouped bar chart in R from the data such that the grouping is on A* and Not A*, the x-axis ticks are CT, VT and TT and the numeric values are plotted in the y-direction.
What do I need to do to produce the bar plot from this raw .csv data?
Next time, you should provide a reproducible example, but I use ggplot2 to create the desired bar plot:
Before jumping into the main body, make sure you have the required packages installed as follows:
install.packages(c("ggplot2","data.table"))
Now for a stacked bar chart:
require(ggplot2)
require(data.table)
data <- data.frame(CT = c( 5.923076923 ,5.555555556),
VT = c(6.529411765,6.434782609),
TT = c(5.305555556, 5.352941176))
rownames(data) <- c("A*", "Not A*")
long_format <- melt(as.matrix(data))
ggplot(long_format, aes(x = Var2,
y = value,
fill = Var1)) +
geom_col()
A grouped bar chart:
ggplot(data = long_format,
aes(x = Var2,
y = value,
fill = Var1)) +
geom_bar(position = "dodge",
stat = "identity")
I want to plot two stacked histograms that share a common x-axis. I want the second histogram to be plotted as the inverse(pointing downward) of the first. I found this post that shows how to plot the stacked histograms (How to plot multiple stacked histograms together in R?). For the sake of simplicity, let's say I just want to plot that same histogram, on the same x-axis but facing in the negative y-axis direction.
You could count up cases and then multiply the count by -1 for one category. Example with data.table / ggplot
library(data.table)
library(ggplot2)
# fake data
set.seed(123)
dat <- data.table(value = factor(sample(1:5, 200, replace=T)),
category = sample(c('a', 'b'), 200, replace=T))
# count by val/category; cat b as negative
plot_dat <-
dat[, .(N = .N * ifelse(category=='a', 1, -1)),
by=.(value, category)]
# plot
ggplot(plot_dat, aes(x=value, y=N, fill=category)) +
geom_bar(stat='identity', position='identity') +
theme_classic()
You can try something like this:
ggplot() +
stat_bin(data = diamonds,aes(x = depth)) +
stat_bin(data = diamonds,aes(x = depth,y = -..count..))
Responding to the additional comment:
library(dplyr)
library(tidyr)
d1 <- diamonds %>%
select(depth,table) %>%
gather(key = grp,value = val,depth,table)
ggplot() +
stat_bin(data = d1,aes(x = val,fill = grp)) +
stat_bin(data = diamonds,aes(x = price,y = -..count..))
Visually, that's a bad example because the scales of the variables are all off, but that's the general idea.
If I want to order the bars in a ggplot2 barchart from largest to smallest, then I'd usually update the factor levels of the bar category, like so
one_group <- data.frame(
height = runif(5),
category = gl(5, 1)
)
o <- order(one_group$height, decreasing = TRUE)
one_group$category <- factor(one_group$category, levels = one_group$category[o])
p_one_group <- ggplot(one_group, aes(category, height)) +
geom_bar(stat = "identity")
p_one_group
If have have several groups of barcharts that I'd like in different facets, with each facet having bars ordered from largest to smallest (and different x-axes) then the technique breaks down.
Given some sample data
two_groups <- data.frame(
height = runif(10),
category = gl(5, 2),
group = gl(2, 1, 10, labels = letters[1:2])
)
and the plotting code
p_two_groups <- ggplot(two_groups, aes(category, height)) +
geom_bar(stat = "identity") +
facet_grid(. ~ group, scales = "free_x")
p_two_groups
what do I need to do to get the bar ordering right?
If it helps, an equivalent problem to solve is: how do I update factor levels after I've done the faceting?
here is a hack:
two_groups <- transform(two_groups, category2 = factor(paste(group, category)))
two_groups <- transform(two_groups, category2 = reorder(category2, rank(height)))
ggplot(two_groups, aes(category2, height)) +
geom_bar(stat = "identity") +
facet_grid(. ~ group, scales = "free_x") +
scale_x_discrete(labels=two_groups$category, breaks=two_groups$category2)
make UNIQUE factor variable for all entries (category2)
reorder the variable based on the height
plot on the variable: aes(x=category2)
re-label the axis using original value (category) for the variable (category2) in scale_x_discrete.
Here is a hack to achieve what you want. I was unable to figure out how to get the category values below the tick marks. So if someone can help fix that, it would be wonderful. Let me know if this works
# add a height rank variable to the data frame
two_groups = ddply(two_groups, .(group), transform, hrank = rank(height));
# plot the graph
p_two_groups <- ggplot(two_groups, aes(-hrank, height)) +
geom_bar(stat = "identity") +
facet_grid(. ~ group, scales = "free_x") +
opts(axis.text.x = theme_blank()) +
geom_text(aes(y = 0, label = category, vjust = 1.5))