I have the following data frame, nothing to fancy about it.
df_bar<-data.frame(capacity = c(no[2],no[1]-no[2],max(df_l$load)-no[1]), type = c("Nuclear","Coal","Gas"),a = c("Optimal","Optimal","Optimal"))
I tried to create a stacked barplot via ggplot, but I also need to make sure that I have a specific order in that plot, with N being the closest to the axis and C the furthest. However, the simple code leads to this.
ggplot(df_bar, aes(y=capacity, x=a, fill=type)) +
geom_bar(position="stack", stat="identity")
How can I maybe alter the code so it respects the order I need?
1.Create a minimal reproducible example.
df_bar<-data.frame(capacity = c(2,2,2),
type = c("Nuclear","Coal","Gas"),
a = c("Optimal","Optimal","Optimal"))
ggplot2 respects the order of ordered factors when plotting. We can use that to our advantage:
library(ggplot2)
ggplot(df_bar, aes(y=capacity, x=a, fill=factor(type, levels=c( "Coal", "Gas", "Nuclear")))) +
geom_bar(position="stack", stat="identity") +
labs(fill="type")
Related
I want to draw a combined bar plot, so that I can make comparision among different score types.
compare_data = data.frame(model=c(lr,rf,gbm,xgboost),
precision=c(0.6593,0.7588,0.6510,0.7344),
recall=c(0.5808,0.6306,0.4897,0.6416),f1=c(0.6176,0.6888,0.5589,0.6848),
acuracy=c(0.6766,0.7393,0.6453,0.7328))
compare1 <- ggplot(evaluation_4model, aes(x=Model, y=Precision)) +
geom_bar(aes(fill = Model), stat="identity")
compare1 <- compare+labs(title = "Precision")
Here is one of the barplot I draw, and this is the type of "precision", however, I want to make a wide bar plot, with all the models under 4 score types sharing the same Y-axis, also with subtitle if possible.
Your code throws an error, because evaluation_4model is not defined.
However, the answer to your problem is likely to make a faceted plot and hence melt the data to a long format. To do this, I usually make use of the reshape library. Tweaking your code looks like this
library(ggplot2)
library(reshape2)
compare_data = data.frame(model=c("lr","rf","gbm","xgboost"),
precision=c(0.6593,0.7588,0.6510,0.7344),
recall=c(0.5808,0.6306,0.4897,0.6416),
f1=c(0.6176,0.6888,0.5589,0.6848),
acuracy=c(0.6766,0.7393,0.6453,0.7328))
plotdata <- melt(compare_data,id.vars = "model")
compare2 <- ggplot(plotdata, aes(x=model, y=value)) +
geom_bar(aes(fill = model), stat="identity")+
facet_grid(~variable)
compare2
does that help?
I'm trying to plot bar graphs in ggplot2 and running into an issue.
Starting with the variables as this
PalList <- c(9, 9009, 906609, 99000099)
PalList1 <- as_tibble(PalList)
Index <- c(1,2,3,4)
PalPlotList <- cbind(Index, PalList)
PPL <- as_tibble(PalPlotList)
and loading the tidyverse library(tidyverse), I tried plotting like this:
PPL %>%
ggplot(aes(x=PalList)) +
geom_bar()
It doesn't matter whether I'm accessing PPL or PalList, I'm still ending up with this (axes and labels may change, but not the chart area):
Even this still gave a blank plot, only now in classic styling:
ggplot(PalList1, aes(value)) +
geom_bar() +
theme_classic()
If I try barplot(PalList), I get an expected result. But I want the control of ggplot. Any suggestions on how to fix this?
An option is to specify the x, y in aes, create the geom_bar with stat as 'identity', and change the x-axis tick labels
library(ggplot2)
ggplot(PPL, aes(x = Index, y = PalList)) +
geom_bar(stat = 'identity') +
scale_x_continuous(breaks = Index, labels = PalList)
I'm having quite the time understanding geom_bar() and position="dodge". I was trying to make some bar graphs illustrating two groups. Originally the data was from two separate data frames. Per this question, I put my data in long format. My example:
test <- data.frame(names=rep(c("A","B","C"), 5), values=1:15)
test2 <- data.frame(names=c("A","B","C"), values=5:7)
df <- data.frame(names=c(paste(test$names), paste(test2$names)), num=c(rep(1,
nrow(test)), rep(2, nrow(test2))), values=c(test$values, test2$values))
I use that example as it's similar to the spend vs. budget example. Spending has many rows per names factor level whereas the budget only has one (one budget amount per category).
For a stacked bar plot, this works great:
ggplot(df, aes(x=factor(names), y=values, fill=factor(num))) +
geom_bar(stat="identity")
In particular, note the y value maxes. They are the sums of the data from test with the values of test2 shown on blue on top.
Based on other questions I've read, I simply need to add position="dodge" to make it a side-by-side plot vs. a stacked one:
ggplot(df, aes(x=factor(names), y=values, fill=factor(num))) +
geom_bar(stat="identity", position="dodge")
It looks great, but note the new max y values. It seems like it's just taking the max y value from each names factor level from test for the y value. It's no longer summing them.
Per some other questions (like this one and this one, I also tried adding the group= option without success (produces the same dodged plot as above):
ggplot(df, aes(x=factor(names), y=values, fill=factor(num), group=factor(num))) +
geom_bar(stat="identity", position="dodge")
I don't understand why the stacked works great and the dodged doesn't just put them side by side instead of on top.
ETA: I found a recent question about this on the ggplot google group with the suggestion to add alpha=0.5 to see what's going on. It isn't that ggplot is taking the max value from each grouping; it's actually over-plotting bars on top of one another for each value.
It seems that when using position="dodge", ggplot expects only one y per x. I contacted Winston Chang, a ggplot developer about this to confirm as well as to inquire if this can be changed as I don't see an advantage.
It seems that stat="identity" should tell ggplot to tally the y=val passed inside aes() instead of individual counts which happens without stat="identity" and when passing no y value.
For now, the workaround seems to be (for the original df above) to aggregate so there's only one y per x:
df2 <- aggregate(df$values, by=list(df$names, df$num), FUN=sum)
p <- ggplot(df2, aes(x=Group.1, y=x, fill=factor(Group.2)))
p <- p + geom_bar(stat="identity", position="dodge")
p
I think the problem is that you want to stack within values of the num group, and dodge between values of num.
It might help to look at what happens when you add an outline to the bars.
library(ggplot2)
set.seed(123)
df <- data.frame(
id = 1:18,
names = rep(LETTERS[1:3], 6),
num = c(rep(1, 15), rep(2, 3)),
values = sample(1:10, 18, replace=TRUE)
)
By default, there are a lot of bars stacked - you just don't see that they're separate unless you have an outline:
# Stacked bars
ggplot(df, aes(x=factor(names), y=values, fill=factor(num))) +
geom_bar(stat="identity", colour="black")
If you dodge, you get bars that are dodged between values of num, but there may be multiple bars within each value of num:
# Dodged on 'num', but some overplotted bars
ggplot(df, aes(x=factor(names), y=values, fill=factor(num))) +
geom_bar(stat="identity", colour="black", position="dodge", alpha=0.1)
If you also add id as a grouping var, it'll dodge all of them:
# Dodging with unique 'id' as the grouping var
ggplot(df, aes(x=factor(names), y=values, fill=factor(num), group=factor(id))) +
geom_bar(stat="identity", colour="black", position="dodge", alpha=0.1)
I think what you want is to both dodge and stack, but you can't do both.
So the best thing is to summarize the data yourself.
library(plyr)
df2 <- ddply(df, c("names", "num"), summarise, values = sum(values))
ggplot(df2, aes(x=factor(names), y=values, fill=factor(num))) +
geom_bar(stat="identity", colour="black", position="dodge")
I'm trying to plot a bar graph of this data
The R script I have written so far is as follows:
library(ggplot2)
f<-read.table("Coverage_test", sep="\t", header=TRUE)
f$Coverage <- factor(f$Coverage, levels=unique(as.character(f$Coverage)))
g = ggplot(data=f, aes(x=Coverage, y=Variable_counts, group=Form, fill=Type))
+ geom_bar(position="dodge", stat="identity", colour="black")
+ facet_grid( ~ Sample_name, scales="free") + opts(title = "Coverage", axis.text.x = theme_text(angle = 90, hjust = 1, size = 8, colour = "grey50"))
+ ylab("Number of variables") + scale_fill_hue() + scale_y_continuous(formatter="comma")
ggsave("Figure_test_coverage.pdf")
The output of this code is as follows:
My question is:
Is there a way to show differences in the behavior of graph based two variables. Each x-axis variable has four bars. I've already chosen to fill the color by 'Type', this shows how different 'Type' (one variable) behaves in my data. But I also want to show how the variable 'Form' behaves in my data. I have grouped them in my code 'group=Form' but can't differentiate it in the actual graph (visually). This can be done in line plots by showing different colors for one variable and different linetypes(solid and dashed) for the other variable. Something like below:
.
I want to know if the 'Form' variable can be shown by different color or atleast can be named below their respective bars or anything that is possible?
Any help is greatly appreciated.
Thank you.
I think you want something like this :
ggplot(data=dat, aes(x=Coverage,
y=Variable_counts,
group=interaction(Form,Type),
fill=interaction(Form,Type))) +
geom_bar(position="dodge", stat="identity", colour="black")
EDIT
Here I would lattice because of barchart and samrt formula notation. For fun I use a ggplot like theme using latticeExtra.
library(latticeExtra)
barchart(Variable_counts~Coverage|Sample_name,
groups=interaction(Type,Form),
data=dat,stack=F,auto.key=list(columns = 4),
par.settings = ggplot2like(),
axis = axis.grid,
between=list(x=2))
Maybe it's because of the dark outside, but I can't get this
Position geom_text on dodged barplot
to work on my fairly simple dataframe
fs <- data.frame(productcategory=c("c2","c2"), product=c("p4", "p5"), ms1=c(2,1))
plot <- ggplot(data=NULL)
plot +
geom_bar(data=fs, aes(x=productcategory, y=ms1, weight=ms1, fill=product),stat="identity", position="dodge") +
geom_text(data=fs, aes(label = ms1, x = productcategory, y=ms1+0.2), position=position_dodge(width=1)))
My plot still shows the labels in the "middle" of the product category and not above of the proper product.
Looks like this even it seems very simple, but I'm totally stuck on this
So any hints are very much appreciated how to get labels above the proper bars.
Tom
Because you have the aesthetics defined for each geom individually, geom_text isn't picking up on the fact that you're subdividing the x variable productcategory by the fill variable product.
You can get the graph you want by adding fill=product to the aes() call for geom_text, or you can try to define as many aesthetics as possible in the original ggplot() call, so that all the geoms pick up on those aesthetics automatically and you only have to define them if they're specific to that particular geom.
plot2 <- ggplot(data=fs, aes(x=productcategory, y=ms1, fill=product)) +
geom_bar(stat="identity", position="dodge") +
geom_text(aes(label=ms1, y =ms1 + 0.2), position=position_dodge(width=1))
print(plot2)