ggplot fill property changes scale - r

I have a simple dataframe and using ggplot to create a bar graph using the code:
ggplot(data=data_cases,aes(x = k,y = val)) +
stat_summary(fun.y=sum, geom = "bar") +
scale_x_discrete(name="Type",
labels=c('A&R','A&E','C&E'))
This code generates the desired result. However when i add a fill property to color the portions of the graph, it changes the y scale. In the image below, the picture on the left has the correct scale, the one on the right is what is produced if the fill property is set (ggplot(data=data_cases,aes(x = k,y = val, fill=state)))
Data:
"k","state","val"
"A&C","SA ",3
"C&E","SA ",2
"A&C","NSW",29
"A&E","NSW",10
"C&E","NSW",11
"C&E","NT ",1
"A&C","WA ",3
"A&E","WA ",1
"C&E","WA ",4
"A&C","VIC",24
"A&E","VIC",1
"C&E","VIC",15
"A&C","QLD",7
"A&E","QLD",2
"C&E","QLD",17

It is because this second chart is showing the number of cases per state, e.g. almost 30 for NSW with type A&R. Each bar is starting from 0.
If you want to be like the original then all the bars should be stacked on top of each other: use position='stack'
ggplot(data=data_cases,aes(x = k,y = val)) +
stat_summary(fun.y=sum, geom = "bar", position="stack") + # <---
scale_x_discrete(name="Type",
labels=c('A&R','A&E','C&E'))
ggplot has a bunch of positions like this. ?position_dodge, ?position_fill, ?position_stack, ?position_identity, ...

can also use geom_col
ggplot(df, aes(k, val, fill = state)) +
geom_col()

Related

GGPLOT BAR CHART not sorting properly with reorder

I am working on a dataset that requires a bar chart and I know the correct way to display this is in a decreasing fashion (i.e.; the largest values on the left and the smallest values on the right). So I used the following code to produce the bar chart:
ggplot(df, aes(x = reorder(province,-gross_profit), y = gross_profit)) +
geom_bar(stat = "identity", fun.y = sum) +
labs(title="Profit by Province")
It does produce a bar chart and in fact changes the order as compared to:
ggplot(df, aes(x = province, y = gross_profit)) +
geom_bar(stat = "identity", fun.y = sum) +
labs(title="Profit by Province")
The reorder code gives me:
The code without reorder gives me:
For clarity:
My Provinces column is a FACTOR type with 10 levels and gross_profit is a NUM type. I have a feeling that you pros will quickly see something I'm obviously missing.

Adding catagory labels on a stacked bar chart in R

I am have a made a geom_col() chart in ggplot2 for which I would like to add labels on the bars, but only one per stacked bar.
This is what my chart looks like without the labels:
gI <- df %>%
ggplot(aes(fill = Category, y=csum, x= tijdas)) +
geom_col()
plot(gI)
And now comes the tricky part. Every stacked bar has is a specific Meeting_type and I would like to add this to the plot. I have tried adding
geom_text(aes(label = Meeting_Type), position = position_dodge(width=0.9), vjust=-0.25)
But this resulted in a label for every category within each bar (so a lot of text):
I would like only one label per (stacked) bar that indicates the Meeting_type. Preferably in a readable place.
Difficult to know the best approach without seeing your data, but it's possible that substituting geom_text for stat_summary would be a good way of summing each column to get the position of the label:
library(ggplot2)
library(dplyr)
mtcars %>%
ggplot(aes(factor(cyl), y = mpg, fill = factor(gear))) +
geom_col() +
stat_summary(aes(label = factor(cyl), fill = NULL),
fun = sum,
geom = "text", vjust = -0.25)
Created on 2020-12-15 by the reprex package (v0.3.0)
As I say, may need a different function for your data - if this isn't a solution then do post a sample using dput and we'll see if we can make it work for your data.

How to make ggplot legend add objects horizontally (vs vertically)

The legend in ggplot can be moved to the bottom of the graphic as a horizontal legend by adding the following arguments to the theme function:
legend.position="bottom" moves the legend below the graph
legend.direction="horizontal" orients the legend to be horizontal.
However, not really...
The legend.direction="horizontal" simply seems to decrease the number of rows in the legend and the number of legend objects in each row.
This can be done manually using guides(color=guide_legend(nrow=x)
dat <- data.frame(plot = rep(letters,2), val = rep(1:length(letters),2))
library(ggplot2)
ggplot(dat, aes(x = val, y = val, color = plot)) +
geom_point() +
theme(legend.position="bottom") +
guides(color=guide_legend(nrow=2))
Regardless....
If you notice in the graphic output of the above code, even though I can control the "dimensions" of my legend (i.e., the number of rows), I can't figure out how to change the ordering of the legend from vertical to horizontal.
So instead of a being above b etc. ("vertically" sorted) as above, I want b to be added next to a ("horizontally" sorted).
How do I make my legend add objects horizontally vs vertically?
Like so:
Try adding byrow = TRUE to guide_legend:
ggplot(dat, aes(x = val, y = val, color = plot)) +
geom_point() +
theme(legend.position="bottom") +
guides(color=guide_legend(nrow=2, byrow = TRUE))

ggplot2 add manual bar to existing plot

I'm trying to add a single, manual bar to the existing area (ribbon) plot. Ideally I just wanted to specify the x (position) and y (value) for the bar.
ExampleData <- data.frame(myID=c(1,2,3,4,5,6,7,8,9,10),PU=c(10,20,30,40,50,60,70,80,90,100))
MyPlot <- ggplot(ExampleData,aes(x=myID))
MyPlot <- MyPlot + geom_ribbon(aes(ymin=0, ymax=PU), fill="lightgray", color="darkgray", size=1)
MyPlot <- MyPlot + geom_col(aes(x=4,y=40), color="red", linetype="solid", size=1)
MyPlot
It is almost working, but for some reason the value of 40 is becoming 400, and ideally I should be able to specify the width of the bar (should be half of what we see below).
Thank you for any help!
Maybe something more like this?
ExampleData <- data.frame(myID=c(1,2,3,4,5,6,7,8,9,10),
PU=c(10,20,30,40,50,60,70,80,90,100))
bar <- data.frame(xmin = 4,xmax= 4.5,ymin = 0,ymax = 40)
ggplot() +
geom_ribbon(data = ExampleData,
aes(x = myID,ymin=0, ymax=PU),
fill="lightgray",
color="darkgray", size=1) +
geom_rect(data = bar,
aes(xmin = xmin,xmax = xmax,ymin = ymin,ymax = ymax),
color = "red")
The 40 vs 400 issue you mention happens when you specify a data frame at the top ggplot() level and then try to add layers where all the aesthetics are intended to be "set" rather than "mapped". The most common case when this happens is when people are adding text labels and you end up with many many copies of each text label plotted on top of each other.
In this case, ggplot is trying to interpret the x and y values you give geom_col in the context of ExampleData, and so ends up repeating those single values 10 times and stacking the resulting bars.

combined bar, line, and point geom in ggplots2- how to change fill on point and dashed line?

Ive worked on this from a previous post: Combined line & bar geoms: How to generate proper legend? And have gotten close. Here is the code I used which adds a line and point geom to the bar plot:
mort12=data.frame(
Adj.S=c(.68,.33,.66,.62,.6,.51,.6,.76,.51,.5),
QTL=c(1:10),
Cum.M=c(.312,.768,NA,.854,NA,.925,.954,NA,NA,.977)
)
ggplot(data=mort12, aes(QTL)) +
geom_bar(aes(y = Adj.S, color = "Adj.S"), stat="identity", fill = "red") +
geom_point(data=mort12[!is.na(mort12$Cum.M),], aes(y = Cum.M, group = 1,size=4, color = "Cum.M"))+
geom_line(data=mort12[!is.na(mort12$Cum.M),],aes(y=Cum.M, linetype="dotted",group = 1))
(Note, I have some missing data for Cum.M, so to connect those points I added code to ignore the missing values).
And when I run this, I get this figure (I cant post pictures here, so its linked):
https://docs.google.com/uc?export=view&id=0B-6a5UsIa6UpZnRZTy1OZmxrY1E
Id like to control the appearance of the line and points. But attempts to make the line dotted (linetype="dotted") did not change it, and when I attempt to change the fill of the dots (fill="white") I ge this error
Error: A continuous variable can not be mapped to shape
Any suggestions on how to alter the attributes of the line and points?
This worked for me:
ggplot(data=mort12, aes(QTL)) +
geom_bar(aes(y = Adj.S, color = "Adj.S"), stat="identity", fill = "white") +
geom_point(data=mort12[!is.na(mort12$Cum.M),], aes(y = Cum.M, group = 1,size=4, color = "Cum.M"))+
geom_line(data=mort12[!is.na(mort12$Cum.M),],aes(y=Cum.M, group = 1), linetype="dotted")
All I did was move linetype outside of aes. Generally speaking, aesthetics that are not driven by your data should not be inside aes. For example, size should probably also not be in aes.

Resources