Change the scale of x axis in ggplot - r

I have a ggplot bar and don't know how to change the scale of the x axis. At the moment it looks like on the image below. However I'd like to reorder the scale of the x axis so that 21% bar is higher than the 7% bar. How could I get the % to the axis? Thanks in advance!
df= data.frame("number" = c(7,21), "name" = c("x","y"))
df
ggplot(df, aes(x=name, y=number)) +
geom_bar(stat="identity", fill = "blue") + xlab("Title") + ylab("Title") +
ggtitle("Title")

Use the prop.table function to in y variable in the geom plot.
ggplot(df, aes(x=name, y=100*prop.table(number))) +
geom_bar(stat="identity", fill = "blue") +
xlab("Stichprobe") + ylab("Paketmenge absolut") +
ggtitle("Menge total")
If you want to have the character, % in the y axis, you can add scale_y_continuous to the plot as below:
library(scales)
ggplot(df, aes(x=name, y=prop.table(number))) +
geom_bar(stat="identity", fill = "blue") +
xlab("Stichprobe") + ylab("Paketmenge absolut") +
ggtitle("Menge total") +
scale_y_continuous(labels=percent)

The only way I am able to duplicate the original plot is, as #sconfluentus noted, for the 7% and 21% to be character strings. As an aside the data frame column names need not be quoted.
df= data.frame(number = c('7%','21%'), name = c("x","y"))
df
ggplot(df, aes(x=name, y=number)) +
geom_bar(stat="identity", fill = "blue") + xlab("Title") + ylab("Title") +
ggtitle("Title")
Changing the numbers to c(0.07, 0.21) and adding, as #Mohanasundaram noted, scale_y_continuous(labels = scales::percent) corrects the situation:
To be pedantic using breaks = c(0.07, 0.21) creates nearly an exact duplicate. See also here.3
Hope this is helpful.
library(ggplot2)
library(scales)
df= data.frame(number = c(0.07,0.21), name = c("KG","MS"))
df
ggplot(df, aes(x=name, y=number)) +
geom_bar(stat="identity", fill = "blue") + xlab("Title") + ylab("Title") +
ggtitle("Title") + scale_y_continuous(labels = scales::percent, breaks = c(.07, .21)))

Related

How to flip a geom_area to be under the line when using scale_y_reverse()

I had to flip the axis of my line, but still need the geom_area to be under the curve. However I cannot figure out how to do so.
This is the line of code I tried
ggplot(PalmBeachWell, aes(x=Date, y=Depth.to.Water.Below.Land.Surface.in.ft.)) +
geom_area(position= "identity", fill='lightblue') +
theme_classic() +
geom_line(color="blue") +
scale_y_reverse()
and here is what i got
One option would be to use a geom_ribbon to fill the area above the curve which after applying scale_y_reverse will result in a fill under the curve.
Using some fake example data based on the ggplot2::economics dataset:
library(ggplot2)
PalmBeachWell <- economics[c("date", "psavert")]
names(PalmBeachWell) <- c("Date", "Depth.to.Water.Below.Land.Surface.in.ft.")
ggplot(PalmBeachWell, aes(x = Date, y = Depth.to.Water.Below.Land.Surface.in.ft.)) +
geom_ribbon(aes(ymin = Depth.to.Water.Below.Land.Surface.in.ft., ymax = Inf),
fill = "lightblue"
) +
geom_line(color = "blue") +
scale_y_reverse() +
theme_classic()

Grouping scale_fill_gradient/continuous grouped bar chart

I am trying to make a grouped bar chart in which the bars are colored based on one variable(binary/ e.g. Group 1 and group2), and then the transparency of the bars are based on another value(continuous/ e.g. p-value), but I want the transparency to be specific to each groups color, and I want the gradient to and legend to be continuous.
I have been able to get close using the color, group, and fill options in geom_bar. You will see that I can get the over all gradient to work and the outlines of the bars are colored correctly. But I would like the fill to be the colors of the outlines and retain the transparency. I also tried using scale_alpha, which maps the transparencies correctly, but doesn't produce a continuous legend.
Here is a small data set like the one I am working with
## data set
d <- data.frame(ID = rep(c(123, 456), 2),
description = rep(c("cancer", "infection"), 2),
variable = c("G2", "G2", "G1", "G1"),
value = c(1.535709, 1.582127, 4.093683, 4.658328),
pvals = c(9.806872e-12, 1.160182e-09, 3.179635e-05, 1.132216e-04))
Here is the ggplot code
ggplot(d, aes(x=reorder(description, -pvals), y=value)) +
geom_bar(stat="identity", aes(col=variable, group=variable, fill=pvals), position="dodge") +
ylim(0, max(d$value) + 0.6) + xlab("") +
coord_flip() +
scale_fill_brewer(palette = "Set1",
name="",
breaks=c("G1", "G2"),
labels=c("Group 1", "Group 2")) +
scale_fill_continuous(trans = 'log10') # I am using log10 transformation because I have many small p-values and this makes the shading look better
Here is attempt 2 where the fill works but the legend does not.
ggplot(d, aes(x=reorder(description, -pvals), y=value)) +
geom_bar(stat="identity", aes(fill=variable, alpha = pvals), position="dodge") +
ylim(0, max(d$value) + 0.6) + xlab("") +
coord_flip() +
scale_fill_brewer(palette = "Set1",
name="",
breaks=c("G1", "G2"),
labels=c("G1", "G2")) +
scale_alpha(trans = "log10")
I've come up with an ugly hack, but it works so here we are. The idea is to first plot your plot as you would per usual, take the layer data and use that as input in a new plot. In this new plot, we make two layers for G1 and G2 and use the ggnewscales package to map these layers to different aesthetics. There are a few caveats I'll warn about.
First, we'll make a plot and save it as a variable:
g <- ggplot(d, aes(x=reorder(description, -pvals), y=value)) +
geom_bar(stat="identity", aes(col=variable, group=variable, fill=pvals), position="dodge") +
ylim(0, max(d$value) + 0.6) + xlab("") +
coord_flip() +
scale_fill_brewer(palette = "Set1",
name="",
breaks=c("G1", "G2"),
labels=c("Group 1", "Group 2")) +
scale_fill_continuous(trans = 'log10')
Next, we'll take the coordinates of this layers data and match them back to the original data. Note that this highly dependent on having unique y-values in your original plot, but I suppose you could also figure this out in other ways.
ld <- layer_data(g)
ld <- ld[, c("xmin", "xmax", "ymin", "ymax")]
# Match back to original data
matches <- match(ld$ymax, d$value)
# Supplement with original data
ld$pvals <- log10(d$pvals[matches])
ld$descr <- d$description[matches]
ld$vars <- d$variable[matches]
Now we'll make a new plot with geom_rects as layers, separated by the vars. In between these layers, we the first fill scale for G1 and use the new_scale_fill() afterwards. Afterwards, we'll do the second geom_rect() and the second fill scale. Then we'll muddle around with the x-axis to have it resemble the original plot somewhat.
library(ggnewscale)
ggplot(mapping = aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax)) +
geom_rect(data = ld[ld$vars == "G1", ], aes(fill = pvals)) +
scale_fill_gradient(low = "red", high = "transparent",
limits = c(min(ld$pvals), 0),
name = "Log10 P-values G1") +
new_scale_fill() +
geom_rect(data = ld[ld$vars == "G2", ], aes(fill = pvals)) +
scale_fill_gradient(low = "blue", high = "transparent",
limits = c(min(ld$pvals), 0),
name = "Log10 P-values G2") +
scale_x_continuous(breaks = seq_along(unique(d$description)),
labels = c("cancer", "infection")) +
coord_flip()
And that's the ugly hack. I might have the x-axis labels wrong, but I've found no elegant way to automatically reproduce the x-axis labels without the code getting too long.
Note: ggnewscales is known to throw errors in older versions of R, but if you use the github version they've fixed that error.
To make the script less verbose and the output is shown below if that is what you're after.
library(ggplot2)
base <- ggplot(d, aes(reorder(description, -pvals), value)) + geom_bar(stat = "identity", aes(col=variable, group=variable, fill=pvals), position = "dodge")
base_axes_flip <- base + ylim(0, max(d$value) + 0.6) + xlab("") + coord_flip()
bax_color <- base_axes_flip + scale_color_manual(values=c('#800020','#00FFFF'),
name="",
breaks=c("G1", "G2"),
labels=c("Group 1", "Group 2"))
# Note here the scale_color_manual
bax_color + scale_fill_continuous(trans = 'log10')
This produces the following output and hope it helps.

Is there a possibility to combine position_stack and nudge_x in a stacked bar chart in ggplot2?

I want to add labels to a stacked bar chart to achieve something like this:
The goal is simple: I need to show market shares and changes versus previous year in the same graph. In theory, I would just add "nudge_x=0.5," to geom_text in the code but I get the error: "Specify either position or nudge_x/nudge_y". Is it possible to use some workaround, maybe another package? Thanks a lot in advance!
Code:
DashboardCategoryText <- c("Total Market","Small Bites","Bars","Total Market","Small Bites","Bars","Total Market","Small Bites","Bars")
Manufacturer <- c("Ferrero","Ferrero","Ferrero","Rest","Rest","Rest","Kraft","Kraft","Kraft")
MAT <- c(-1,5,-7,6,8,10,-10,5,8)
Measure_MATCurrent <- c(500,700,200,1000,600,80,30,60,100)
data <- data.frame(DashboardCategoryText,Manufacturer,MAT,Measure_MATCurrent)
library(dplyr)
groupedresult <- group_by(data,DashboardCategoryText)
groupedresult <- summarize(groupedresult,SUM=sum(Measure_MATCurrent))
groupedresult <- as.data.frame(groupedresult)
data <- merge(data,groupedresult,by="DashboardCategoryText")
data$percent <- data$Measure_MATCurrent/data$SUM
library(ggplot2)
ggplot(data, aes(x=reorder(DashboardCategoryText, SUM), y=percent, fill=Manufacturer)) +
geom_bar(stat = "identity", width = .7, colour="black", lwd=0.1) +
geom_text(aes(label=ifelse(percent >= 0.005, paste0(sprintf("%.0f", percent*100),"%"),"")),
position=position_stack(vjust=0.5), colour="white") +
geom_text(aes(label=MAT,y=percent),
nudge_x=0.5,
position=position_stack(vjust=0.8),
colour="black") +
coord_flip() +
scale_y_continuous(labels = percent_format()) +
labs(y="", x="")
I have a somewhat 'hacky' solution where you essentially just change the geom_text data in the underlying ggplot object before you plot it.
p <- ggplot(data, aes(x=reorder(DashboardCategoryText, SUM), y=percent, fill=Manufacturer)) +
geom_bar(stat = "identity", width = .7, colour="black", lwd=0.1) +
geom_text(aes(label=ifelse(percent >= 0.005, paste0(sprintf("%.0f", percent*100),"%"),"")),
position=position_stack(vjust=0.5), colour="white") +
geom_text(aes(label=MAT,y=percent),
position=position_stack(vjust=.5),
colour="black") +
coord_flip() +
scale_y_continuous(labels = percent_format()) +
labs(y="", x="")
q <- ggplot_build(p) # get the ggplot data
q$data[[3]]$x <- q$data[[3]]$x + 0.5 # change it to adjust the x position of geom_text
plot(ggplot_gtable(q)) # plot everything

I want to change the color of ggplot bar charts

I want to change the color of ggplot bar charts manually using the scale_color_manual function. Here is the code:
library(ggplot2)
ggplot(UM.Leads, aes(Leads, Count, fill = Model)) +
geom_bar(stat = "identity") +
xlab("Electrode Model") +
ylab("DBS Leads") +
ggtitle("University of Minnesota") +
scale_color_manual(values = c("darkgoldenrod1", "grey55", "dodgerblue1")) +
theme_classic()
I cannot seem to change the fill of the bar graphs from the default pink, green, and blue that ggplot provides. Any help would be much appreciated!
See plot here: http://rpubs.com/Gopher16/393415
To illustrate the comment from #Jack Brookes and create a reproducible example:
library(ggplot2)
df <- data.frame(
gp = factor(rep(letters[1:3], each = 10)),
y = rnorm(30)
)
ggplot(df, aes(gp, y, fill=gp)) +
geom_bar(stat = "identity") +
scale_fill_manual(values = c("darkgoldenrod1", "grey55", "dodgerblue1")) +
theme_classic()

can one offset jitter points in ggplot boxplot

In a ggplot boxplot, it is easy to use jitter to add the raw data points with varying degrees of jitter. With zero jitter the following code
dat <- data.frame(group=c('a', 'b', 'c'), values = runif(90))
ggplot(dat, aes(group, values)) +
geom_boxplot(outlier.size = 0) +
geom_jitter(position=position_jitter(width=0), aes(colour=group), alpha=0.7) +
ylim(0, 1) + stat_summary(fun.y=mean, shape=3, col='red', geom='point') +
opts(legend.position = "right") + ylab("values") + xlab("group")
produces the plot below.
Is it possible to use zero jitter but add an offset such that the points are in a line but shifted left by 25% of the box width? I tried geom_point with dodge but this generated a jitter.
If we convert group to numeric and then add an offset, you seem to get your desired output. There is probably a more effective / efficient way, but give this a whirl:
ggplot(dat, aes(group, values)) +
geom_boxplot(outlier.size = 0) +
geom_point(aes(x = as.numeric(group) + .25, colour=group), alpha=0.7) +
ylim(0, 1) + stat_summary(fun.y=mean, shape=3, col='red', geom='point') +
opts(legend.position = "right") + ylab("values") + xlab("group")

Resources