ggplot2 coord_flip() with geom_text - r

I'm trying to find a way to easily flip a plot annotated with geom_text(). The problem is that if I use coord_flip(), the labels are kind of not flipped.
A simple example, if I flip the plot like that:
df <- count(diamonds, cut)
ggplot(df, aes(x = cut, y = n, label = n)) +
geom_bar(stat = "identity") +
geom_text()
by adding coord_flip(), I'm getting:
I know that this could be a desired behaviour in some cases but instead of that, I need the labels on the bars to stay aligned with the bars and look more like:
Is there any solution to that?

You can use the angle aesthetic in geom_text, setting it to a fixed value.
ggplot(df, aes(x = cut, y = n, label = n)) +
geom_bar(stat = "identity") +
geom_text(angle = 270) +
coord_flip()

Related

In ggplot, how can I get two legends ("gradient" type) for stat_bin2d?

Here I have two 'clusters', and just one legend.
How can I get two "density" legends with two different color gradients?
I have tried group but it does not work.
The following code generated the above graph:
library(ggplot2)
df <- data.frame(x=c(rnorm(1000,1,.1),rnorm(1000,3,.1)),
y=c(rnorm(1000,1,1),rnorm(1000,3,1)),
type=c(rep('a',1000),rep('b',1000)))
plot( ggplot(df) +
stat_bin2d(aes(x,y,fill=..density..,group='type')))
I'm not aware of a way to specify more than one fill gradient. But here's a work around that uses different transparency levels to simulate the gradient, leaving fill available to be mapped with type:
ggplot(df, aes(x, y, fill = type)) +
stat_bin2d(aes(alpha = ..density..)) +
scale_alpha(range = c(1, 0.1)) +
theme_bw()
Using alpha = ..density.. does the trick:
ggplot(df, aes(x = x, y = y) ) +
stat_bin2d(mapping= aes(alpha = ..density.., fill = type))
A bit more aesthetically using stat_density2d e.g.:
ggplot(df, aes(x=x, y=y) ) +
stat_density2d(mapping= aes(alpha = ..level.., color= type), geom="contour", bins=6, size= 2)

ggplot2: how to reduce space between narrow width bars, after coord_flip, and panel border

When you have flipped coordinates, how do you reduce the space between bars that are narrow and the panel border? Using the data frame df and the ggplot commands, there is much white space between the bottom bar and the tick marks (and similarly a wide space above the "vendor" bar).
df <- data.frame(x = c("firm", "vendor"), y = c(50, 20))
ggplot(df, aes(x = x, y = y)) +
geom_bar(stat = "identity", width = 0.4) +
theme_tufte() + coord_flip() +
labs(x = "", y = "")
I tried scale_x_discrete with both limits and expand arguments to no avail as well as position = position dodge, likewise with no effect.
This question offers coord_equal to change the aspect ratio, and thereby reduce or eliminate the extra space, but notes that the solution does not work with coord_flip.
I think I have found a solution. You can remove width from geom_bar and introduce theme(aspect.ratio = .2), then you can play with the ratio to find the desired width. And unlike coord_equal or coord_fixed is compatible with coord_flip.
ggplot(df, aes(x = x, y = y)) +
geom_bar(stat = "identity") +
theme_tufte() + theme(aspect.ratio = .2) +
coord_flip() +
labs(x = "", y = "")

geom_histogram and data labels [duplicate]

Below code works well and it labels the barplot correctly, However, if I try geom_text for a histogram I fail since geom_text requires a y-component and a histogram's y component is not part of the original data.
Label an "ordinary" bar plot (geom_bar(stat = "identity") works well:
ggplot(csub, aes(x = Year, y = Anomaly10y, fill = pos)) +
geom_bar(stat = "identity", position = "identity") +
geom_text(aes(label = Anomaly10y,vjust=1.5))
My Problem: How to get the correct y and label (indicated by ?) for geom_text, to put labels on top of the histogram bars
ggplot(csub,aes(x = Anomaly10y)) +
geom_histogram()
geom_text(aes(label = ?, vjust = 1.5))
geom_text requires x, y and labels. However, y and labels are not in the original data, but generated by the geom_histogram function. How can I extract the necessary data to position labels on a histogram?
geom_histogram() is just a fancy wrapper to stat_bin so you can all that yourself with the bars and text that you like. Here's an example
#sample data
set.seed(15)
csub<-data.frame(Anomaly10y = rpois(50,5))
And then we plot it with
ggplot(csub,aes(x=Anomaly10y)) +
stat_bin(binwidth=1) + ylim(c(0, 12)) +
stat_bin(binwidth=1, geom="text", aes(label=..count..), vjust=-1.5)
to get
Ok to make it aesthetically appealing here is the solution:
set.seed(15)
csub <- data.frame(Anomaly10y = rpois(50, 5))
Now Plot it
csub %>%
ggplot(aes(Anomaly10y)) +
geom_histogram(binwidth=1) +
stat_bin(binwidth=1, geom='text', color='white', aes(label=..count..),
position=position_stack(vjust = 0.5))
resultant plot will be

Get values and positions to label a ggplot histogram

Below code works well and it labels the barplot correctly, However, if I try geom_text for a histogram I fail since geom_text requires a y-component and a histogram's y component is not part of the original data.
Label an "ordinary" bar plot (geom_bar(stat = "identity") works well:
ggplot(csub, aes(x = Year, y = Anomaly10y, fill = pos)) +
geom_bar(stat = "identity", position = "identity") +
geom_text(aes(label = Anomaly10y,vjust=1.5))
My Problem: How to get the correct y and label (indicated by ?) for geom_text, to put labels on top of the histogram bars
ggplot(csub,aes(x = Anomaly10y)) +
geom_histogram()
geom_text(aes(label = ?, vjust = 1.5))
geom_text requires x, y and labels. However, y and labels are not in the original data, but generated by the geom_histogram function. How can I extract the necessary data to position labels on a histogram?
geom_histogram() is just a fancy wrapper to stat_bin so you can all that yourself with the bars and text that you like. Here's an example
#sample data
set.seed(15)
csub<-data.frame(Anomaly10y = rpois(50,5))
And then we plot it with
ggplot(csub,aes(x=Anomaly10y)) +
stat_bin(binwidth=1) + ylim(c(0, 12)) +
stat_bin(binwidth=1, geom="text", aes(label=..count..), vjust=-1.5)
to get
Ok to make it aesthetically appealing here is the solution:
set.seed(15)
csub <- data.frame(Anomaly10y = rpois(50, 5))
Now Plot it
csub %>%
ggplot(aes(Anomaly10y)) +
geom_histogram(binwidth=1) +
stat_bin(binwidth=1, geom='text', color='white', aes(label=..count..),
position=position_stack(vjust = 0.5))
resultant plot will be

How to annotate geom_bar above bars?

I'm trying to do a simple plot using ggplot2:
library(ggplot2)
ggplot(diamonds, aes(x = cut, y = depth)) +
geom_bar(stat = "identity", color = "blue") +
facet_wrap(~ color) +
geom_text(aes(x = cut, y = depth, label = cut, vjust = 0))
How can I annotate this plot so that I get annotations above bars? Now geom_text puts labels at the bottom of the bars, but I want them above these bars.
You can use stat_summary() to calculate position of y values as sum of depth and use geom="text" to add labels. The sum is used because your bars shows the sum of depth values for each cut value.
As suggest by #joran it is better to use stat_summary() instead of geom_bar() to show sums of y values because stat="identity" makes problems due to overplotting of bars and if there will be negative values then bar will start in negative part of plot and end in positive part - result will be not the actual sum of values.
ggplot(diamonds[1:100,], aes(x = cut, y = depth)) +
facet_wrap(~ color) +
stat_summary(fun.y = sum, geom="bar", fill = "blue", aes(label=cut, vjust = 0)) +
stat_summary(fun.y = sum, geom="text", aes(label=cut), vjust = 0)
You can also precalculate sum of depth values and the you can use geom_bar() with stat="identity" and geom_text().
library(plyr)
diamonds2<-ddply(diamonds,.(cut,color),summarise,depth=sum(depth))
ggplot(diamonds2,aes(x=cut,y=depth))+
geom_bar(stat="identity",fill="blue")+
geom_text(aes(label=cut),vjust=0,angle=45,hjust=0)+
facet_wrap(~color)

Resources