How Can I Increase Space Between Bars With ggplot? - r

ggplot(G, aes(x=State, y=Score, fill=State))+
geom_bar(stat="identity", position="dodge")+
scale_y_continuous(labels = scales::comma)
Please help me make more elegant to read.
this output
+ I wanna use a line in x at the score of 236, tried
abline( v=236)
did not work!

Try this, it works for me
barplot(c(1,2,3,4),space=c(1,1,1,1)) # equally spaced bars as expected
barplot(c(1,2,3,4),space=c(1,20,1,1)) # massive gap before the 2nd bar
barplot(c(1,2,3,4),space=c(20,1,1,1)) # the same as the first plot

That's a lot of bars. You can make the bars narrower by specifying their width inside geom_bar() (as a proportion, 1 is touching, 0.5 is equal amounts of bar and gap, the default is 0.9).
ggplot(G, aes(x = State, y = Score, fill = State)) +
geom_bar(stat = "identity", position = "dodge", width = 0.8) +
scale_y_continuous(labels = scales::comma)
Also note that the position = "dodge" isn't doing anything in your example.
For a plot with that many bars, if you want them all labeled, I would suggest adding + coord_flip() to your plot - usually it's easier to have lots of vertical space than lots of horizontal space, and the long labels won't overlap. When you have over 50 bars, you're going to need a fair amount of space.

Related

What does the height of bars in the two bar chats with different "position" represents?

I know in this command line the height of the bars represents the count of each group in this variable "color":
ggplot(diamonds, aes(color, fill = cut)) +
geom_bar()
But I really wanna know what about this command line:
ggplot(diamonds, aes(color, fill = cut)) +
geom_bar(alpha=0.5, position = "identity")
I know the former is defaulted as position "stack" and I also know the meaning of position "identity". But I really can't figure out what the height of the bars in the later one represents?
Thanks many in advance!
I think the best way to understand it is to imagine using position='dodge' (which places multiple bars for different cuts, separated by color) and instead layering all the cut bars on top of each other.
ggplot(diamonds, aes(color, fill = cut)) +
geom_bar(alpha=0.5, position = "dodge")
ggplot(diamonds, aes(color, fill = cut)) +
geom_bar(alpha=0.5, position = "identity")
(Note, the colors get distorted because the 'Fair' cut is in front.)
When you use position=stack, for each x position counts per group in the fill are.stacked on top.of each other..with position=identity on the other hand for each x position if there are multiple groups in the fill varaibles they also start at y=0 and are essentially overlaid.

hHw to make width of bars equal in ggplot2 barplot?

I am trying to make the width of all bars in the following plot equal. Can anybody help me? is it possible? or is there any way to plot this data?
library(ggplot2)
dat <- data.frame(x = c('I','I','I','I','II','II'),
y = LETTERS[1:6],
z = abs(rnorm(6)))
ggplot(dat, aes(y,z))+
geom_bar(stat = "identity") +
facet_wrap(~x,scales="free")
I also tried using arguments size and width inside the geom_bar but its not working.
Really the problem is that each of the facet panels is being forced to be the same size and then the plot inside expands to fill all the available room. With facet_grid you can adjust the space for each facet panel (but you cannot seem to do this with facet_wrap). Try
ggplot(dat, aes(y,z))+
geom_bar(stat = "identity") +
facet_grid(~x,scales="free", space="free_x")
which gives me

In ggplot2, can borders of bars be changed on only one side? (color, thickness)

I know, 3D Barcharts are a sin. But i´m asked to do them and as a trade-off i suggested to only make a border with a slightly darker color than the bar´s on the top and the right side of the bar. Like that, the bars would have some kind of "shadow" (urgh) but at least you still would be able to compare them.
Is there any way to do this?
ggplot(diamonds, aes(clarity)) + geom_bar()
Another possibility, using two sets of geom_bar. The first set, the green ones, are made slightly higher and offset to the right. I borrow the data from #Didzis Elferts.
ggplot(data = df2) +
geom_bar(aes(x = as.numeric(clarity) + 0.1, y = V1 + 100),
width = 0.8, fill = "green", stat = "identity") +
geom_bar(aes(x = as.numeric(clarity), y = V1),
width = 0.8, stat = "identity") +
scale_x_continuous(name = "clarity",
breaks = as.numeric(df2$clarity),
labels = levels(df2$clarity))+
ylab("count")
As you already said - 3D barcharts are "bad". You can't do it directly in ggplot2 but here is a possible workaround for this.
First, make new data frame that contains levels of clarity and corresponding count for each level.
library(plyr)
df2<-ddply(diamonds,.(clarity),nrow)
Then in ggplot() call use new data frame and clarity as x values and V1 (counts) as y values and add geom_blank() - this will make x axis with levels we need. Then add geom_rect() to produce shading for bars - here xmin and xmax values are made as.numeric() from clarity and constant is added - for xmin constant should be less than half of bars width and xmax constant larger than half of bars width. ymin is 0 and ymax is V1 (counts) plus some constant. Finally add geom_bar(stat="identity") above this shadow to plot actually barplot.
ggplot(df2,aes(clarity,V1)) + geom_blank()+
geom_rect(aes(xmin=as.numeric(clarity)-0.38,
xmax=as.numeric(clarity)+.5,
ymin=0,
ymax=V1+250),fill="green")+
geom_bar(width=0.8,stat="identity")

How to make dodge in geom_bar agree with dodge in geom_errorbar, geom_point

I have a dataset where measurements are made for different groups at different days.
I want to have side by side bars representing the measurements at the different days for the different groups with the groups of bars spaced according to day of measurement with errorbars overlaid to them.
I'm having trouble with making the dodging in geom_bar agree with the dodge on geom_errorbar.
Here is a simple piece of code:
days = data.frame(day=c(0,1,8,15));
groups = data.frame(group=c("A","B","C","D", "E"), means=seq(0,1,length=5));
my_data = merge(days, groups);
my_data$mid = exp(my_data$means+rnorm(nrow(my_data), sd=0.25));
my_data$sigma = 0.1;
png(file="bar_and_errors_example.png", height=900, width=1200);
plot(ggplot(my_data, aes(x=day, weight=mid, ymin=mid-sigma, ymax=mid+sigma, fill=group)) +
geom_bar (position=position_dodge(width=0.5)) +
geom_errorbar (position=position_dodge(width=0.5), colour="black") +
geom_point (position=position_dodge(width=0.5), aes(y=mid, colour=group)));
dev.off();
In the plot, the errorsegments appears with a fixed offset from its bar (sorry, no plots allowed for newbies even if ggplot2 is the subject).
When binwidth is adjusted in geom_bar, the offset is not fixed and changes from day to day.
Notice, that geom_errorbar and geom_point dodge in tandem.
How do I get geom_bar to agree with the other two?
Any help appreciated.
The alignment problems are due, in part, to your bars not representing the data you intend. The following lines up correctly:
ggplot(my_data, aes(x=day, weight=mid, ymin=mid-sigma, ymax=mid+sigma, fill=group)) +
geom_bar (position=position_dodge(), aes(y=mid), stat="identity") +
geom_errorbar (position=position_dodge(width=0.9), colour="black") +
geom_point (position=position_dodge(width=0.9), aes(y=mid, colour=group))
This is an old question, but since i ran into the problem today, i want to add the following:
In
geom_bar(position = position_dodge(width=0.9), stat = "identity") +
geom_errorbar( position = position_dodge(width=0.9), colour="black")
the width-argument within position_dodge controls the dodging width of the things to dodge from each other. However, this produces whiskers as wide as the bars, which is possibly undesired.
An additional width-argument outside the position_dodge controls the width of the whiskers (and bars):
geom_bar(position = position_dodge(width=0.9), stat = "identity", width=0.7) +
geom_errorbar( position = position_dodge(width=0.9), colour="black", width=0.3)
The first change I reformatted the code according to the advanced R style guide.
days <- data.frame(day=c(0,1,8,15))
groups <- data.frame(
group=c("A","B","C","D", "E"),
means=seq(0,1,length=5)
)
my_data <- merge(days, groups)
my_data$mid <- exp(my_data$means+rnorm(nrow(my_data), sd=0.25))
my_data$sigma <- 0.1
Now when we look at the data we see that day is a factor and everything else is the same.
str(my_data)
To remove blank space from the plot I converted the day column to factors. CHECK that the levels are in the proper order before proceeding.
my_data$day <- as.factor(my_data$day)
levels(my_data$day)
The next change I made was defining y in your aes arguments. As I'm sure you are aware, this lets ggplot know where to look for y values. Then I changed the position argument to "dodge" and added the stat="identity" argument. The "identity" argument tells ggplot to plot y at x. geom_errorbar inherits the dodge position from geom_bar so you can leave it unspecified, but geom_point does not so you must specify that value. The default dodge is position_dodge(.9).
ggplot(data = my_data,
aes(x=day,
y= mid,
ymin=mid-sigma,
ymax=mid+sigma,
fill=group)) +
geom_bar(position="dodge", stat = "identity") +
geom_errorbar( position = position_dodge(), colour="black") +
geom_point(position=position_dodge(.9), aes(y=mid, colour=group))
sometimes you put aes(x=tasks,y=val,fill=group) in geom_bar rather than ggplot. This causes the problem since ggplot looks forward x and you specify it by the location of each group.

How to increase the space between the bars in a bar plot in ggplot2?

How can I increase the space between the bars in a bar plot in ggplot2 ?
You can always play with the width parameter, as shown below:
df <- data.frame(x=factor(LETTERS[1:4]), y=sample(1:100, 4))
library(ggplot2)
ggplot(data=df, aes(x=x, y=y, width=.5)) +
geom_bar(stat="identity", position="identity") +
opts(title="width = .5") + labs(x="", y="") +
theme_bw()
Compare with the following other settings for width:
So far, so good. Now, suppose we have two factors. In case you would like to play with evenly spaced juxtaposed bars (like when using space together with beside=TRUE in barplot()), it's not so easy using geom_bar(position="dodge"): you can change bar width, but not add space in between adjacent bars (and I didn't find a convenient solution on Google). I ended up with something like that:
df <- data.frame(g=gl(2, 1, labels=letters[1:2]), y=sample(1:100, 4))
x.seq <- c(1,2,4,5)
ggplot(data=transform(df, x=x.seq), aes(x=x, y=y, width=.85)) +
geom_bar(stat="identity", aes(fill=g)) + labs(x="", y="") +
scale_x_discrete(breaks = NA) +
geom_text(aes(x=c(sum(x.seq[1:2])/2, sum(x.seq[3:4])/2), y=0,
label=c("X","Y")), vjust=1.2, size=8)
The vector used for the $x$-axis is "injected" in the data.frame, so that so you change the outer spacing if you want, while width allows to control for inner spacing. Labels for the $x$-axis might be enhanced by using scale_x_discrete().
For space between factor bars use
ggplot(data = d, aes(x=X, y=Y, fill=F))
+ geom_bar(width = 0.8, position = position_dodge(width = 0.9))
The width in geom_bar controls the bar width in relation to the x-axis while the width in position_dodge control the width of the space given to both bars also in relation to the x-axis. Play around with the width to find one that you like.
Thank you very much chl.! I had the same problem and you helped me solving it. Instead of using geom_text to add the X-labels I used scale_x_continuous (see below)
geom_text(aes(x=c(sum(x.seq[1:2])/2, sum(x.seq[3:4])/2), y=0,
label=c("X","Y")), vjust=1.2, size=8)
replaced by
scale_x_continuous(breaks=c(mean(x.seq[1:2]), mean(x.seq[3:4])), labels=c("X", "Y"))
For space between POSIXlt bars you need adjust the width from the number of seconds in a day
# POSIXlt example: full & half width
d <- data.frame(dates = strptime(paste(2016, "01", 1:10, sep = "-"), "%Y-%m-%d"),
values = 1:10)
ggplot(d, aes(dates, values)) +
geom_bar(stat = "identity", width = 60*60*24)
ggplot(d, aes(dates, values)) +
geom_bar(stat = "identity", width = 60*60*24*0.5)

Resources