This question already has answers here:
geom_bar bars not displaying when specifying ylim
(4 answers)
Closed 17 days ago.
I want to draw a bar chart with ggplot2 along with custom y limits.
Type <- LETTERS[1:5]
Y <- c(99, 99.5, 99.0, 98.8, 98.5)
df <- data.frame(Type, Y)
The following code works fine for bar chart:
library(ggplot2)
ggplot(data = df, mapping = aes(x = Type, y = Y, fill = Type)) +
geom_bar(stat = "identity") +
theme_bw()
However, I'm not able to set the y limits. See the code below.
ggplot(data = df, mapping = aes(x = Type, y = Y, fill = Type)) +
geom_bar(stat = "identity") +
scale_y_continuous(limits = c(90, 100)) +
theme_bw()
ggplot(data = df, mapping = aes(x = Type, y = Y, fill = Type)) +
geom_bar(stat = "identity") +
ylim(90, 100) +
theme_bw()
Edited
I guess this behavior is due to stat = "identity".
Alternative, using coord_cartesian:
ggplot(data = df, mapping = aes(x = Type, y = Y, fill = Type)) +
geom_bar(stat = "identity") +
coord_cartesian(ylim = c(90, 100)) +
theme_bw()
Gives you:
Solution using geom_rect() instead of geom_bar():
# Generate data
Type <- LETTERS[1:5]
Y <- c(99, 99.5, 99.0, 98.8, 98.5)
df <- data.frame(Type, Y)
# Plot data
library(ggplot2)
ggplot() +
geom_rect(data = df,
aes(xmin = as.numeric(Type) - 0.3,
xmax = as.numeric(Type) + 0.3,
ymin = 90, ymax = Y,
fill = Type)) +
scale_x_continuous(label = df$Type, breaks = 1:nrow(df))
In geom_rect() specify x coordinates as as.numeric(X) -/+ value; ymin coordinates as wanted lower limit and ymax as actual Y values.
Related
I have the following graph and code:
Graph
ggplot(long2, aes(x = DATA, y = value, fill = variable)) + geom_area(position="fill", alpha=0.75) +
scale_y_continuous(labels = scales::comma,n.breaks = 5,breaks = waiver()) +
scale_fill_viridis_d() +
scale_x_date(date_labels = "%b/%Y",date_breaks = "6 months") +
ggtitle("Proporcions de les visites, només 9T i 9C") +
xlab("Data") + ylab("% visites") +
theme_minimal() + theme(legend.position="bottom") + guides(fill=guide_legend(title=NULL)) +
annotate("rect", fill = "white", alpha = 0.3,
xmin = as.Date.character("2020-03-16"), xmax = as.Date.character("2020-06-22"),
ymin = 0, ymax = 1)
But it has some sawtooth, how am I supposed to smooth it out?
I believe your situation is roughly analogous to the following, wherein we have missing x-positions for one group, but not the other at the same position. This causes spikes if you set position = "fill".
library(ggplot2)
x <- seq_len(100)
df <- data.frame(
x = c(x[-c(25, 75)], x[-50]),
y = c(cos(x[-c(25, 75)]), sin(x[-50])) + 5,
group = rep(c("A", "B"), c(98, 99))
)
ggplot(df, aes(x, y, fill = group)) +
geom_area(position = "fill")
To smooth out these spikes, it has been suggested to linearly interpolate the data at the missing positions.
# Find all used x-positions
ux <- unique(df$x)
# Split data by group, interpolate data groupwise
df <- lapply(split(df, df$group), function(xy) {
approxed <- approx(xy$x, xy$y, xout = ux)
data.frame(x = ux, y = approxed$y, group = xy$group[1])
})
# Recombine data
df <- do.call(rbind, df)
# Now without spikes :)
ggplot(df, aes(x, y, fill = group)) +
geom_area(position = "fill")
Created on 2022-06-17 by the reprex package (v2.0.1)
P.S. I would also have expected a red spike at x=50, but for some reason this didn't happen.
I'm struggling with the following issue:
I want to plot two histograms, but since the statistics of one of the two classes is much less than the other I need to add a second y-axis to allow a direct comparison of the values.
I report below the code I used at the moment and the result.
Thank you in advance!
ggplot(data,aes(x= x ,group=class,fill=class)) + geom_histogram(position="identity",
alpha=0.5, bins = 20)+ theme_bw()
Consider the following situation where you have 800 versus 200 observations:
library(ggplot2)
df <- data.frame(
x = rnorm(1000, rep(c(1, 2), c(800, 200))),
class = rep(c("A", "B"), c(800, 200))
)
ggplot(df, aes(x, fill = class)) +
geom_histogram(bins = 20, position = "identity", alpha = 0.5,
# Note that y = stat(count) is the default behaviour
mapping = aes(y = stat(count)))
You could scale the counts for each group to a maximum of 1 by using y = stat(ncount):
ggplot(df, aes(x, fill = class)) +
geom_histogram(bins = 20, position = "identity", alpha = 0.5,
mapping = aes(y = stat(ncount)))
Alternatively, you can set y = stat(density) to have the total area integrate to 1.
ggplot(df, aes(x, fill = class)) +
geom_histogram(bins = 20, position = "identity", alpha = 0.5,
mapping = aes(y = stat(density)))
Note that after ggplot 3.3.0 stat() probably will get replaced by after_stat().
How about comparing them side by side with facets?
ggplot(data,aes(x= x ,group=class,fill=class)) +
geom_histogram(position="identity",
alpha=0.5,
bins = 20) +
theme_bw() +
facet_wrap(~class, scales = "free_y")
I want to know how to turn this plot:
Into this plot:
As you can see the panel and axis on the 2nd plot are limited to the data extent. I made the second graph using design software but want to know the code.
Ive already limited the x and y axis using
xlim and ylim but no difference.
Please see my code below, sorry its so messy, first time using r studio. Thanks!
ggplot() +
geom_errorbar(data = U1483_Coiling_B_M_Removed_R, mapping = aes(x = `Age (Ma) Linear Age Model`, ymin = `Lower interval*100`, ymax = `Upper interval*100`), width = 0.025, colour = 'grey') +
geom_line(data = U1483_Coiling_B_M_Removed_R, aes(x = `Age (Ma) Linear Age Model`, y = `Percent Dextral`)) +
geom_point(data = U1483_Coiling_B_M_Removed_R, aes(x = `Age (Ma) Linear Age Model`, y = `Percent Dextral`), colour = 'red') +
geom_point(data = U1483_Coiling_B_M_Removed_R, aes(x = `Age (Ma) Linear Age Model`, y = `Lab?`)) +
theme(axis.text.x=element_text(angle=90, size=10, vjust=0.5)) +
theme(axis.text.y=element_text(angle=90, size=10, vjust=0.5)) +
theme_classic() +
theme(panel.background = element_rect(colour = 'black', size = 1)) +
xlim(0, 2.85) +
ylim(0, 100)
You can use expand when specifying axis scales, like so:
# Load library
library(ggplot2)
# Set RNG
set.seed(0)
# Create dummy data
df <- data.frame(x = seq(0, 3, by = 0.1))
df$y <- 100 - abs(rnorm(nrow(df), 0, 10))
# Plot results
# Original
ggplot(df, aes(x, y)) +
geom_line() +
geom_point(colour = "#FF3300", size = 5)
# With expand
ggplot(df, aes(x, y)) +
geom_line() +
geom_point(colour = "#FF3300", size = 5) +
scale_y_continuous(expand = c(0, 0))
g = ggplot(Values, aes(x = X, y = Y, fill=factor(Z))) +
geom_bar(width=0.8, stat = "identity", position="dodge") +
facet_grid(Z ~ ., scale = "free_y") +
labs(x="Anno", y = "Riserva Rivalutata") +
theme(legend.position ="none") +
scale_x_continuous(breaks = seq(2000, 2070, by = 5))
d = ggplot(Values, aes(x = X, y = Y, fill=factor(Z))) +
geom_bar(width=0.8, stat = "identity", position="dodge")
p = subplot(g,d, nrows=2, shareX= T,which_layout = 1)
Hello,
I'm creating an object that when I click 2 objects Z, shows me above 2 distinct graphs, while below I would like to see the subtraction of the two.
Right now I can only see them distinct.
Can you help me to make a single chart but with only one bar given by the difference between the two data?
Thank you
I am designing a bar plot with ggplot2 package.
The only problem is that I cannot get rid of the space between the bars and the x-axis.
I know that this formula should resolve the problem:
scale_y_continuous(expand = c(0, 0)) function
But it seems that the element for the error bar is overwriting it and gives always this space.
here my code:
p<-ggplot(data=tableaumergectrlmut, aes(x=ID, y=meanNSAFbait, fill=Condition)) +
geom_bar(stat="identity", position=position_dodge())+
scale_y_continuous(expand = c(0,0))+
geom_errorbar(aes(ymin=meanNSAFbait-SDNSAFbait,
ymax=meanNSAFbait+SDNSAFbait, width=0.25), position=position_dodge(.9))
Using some example data to generate a plot that (I think) shows the problem you're having.
library(ggplot2)
df <- data.frame(val = c(10, 20, 100, 5), name = LETTERS[1:4])
ggplot(df, aes(x = name, y = val, fill = name)) +
geom_bar(stat = "identity")
There is a gap from the zero point on the y axis (bottom of the bars) and where the x axis labels are.
You can remove this using scale_y_discrete or scale_y_continuous, depending on the nature of your data, and setting expand to c(0,0):
ggplot(df, aes(x = name, y = val, fill = name)) +
geom_bar(stat = "identity") +
scale_y_discrete(expand = c(0,0)) +
scale_x_discrete(expand = c(0,0))
This gives the plot:
Note I've also removed the gap along the y axis, simply remove the scale_x_discrete line to add this gap back in.
Since error bars are an issue, here are a few examples:
ggplot(df, aes(x = name, y = val, fill = name)) +
geom_bar(stat = "identity") +
geom_errorbar(aes(ymin = val - 10,
ymax = val + 10))
You can use scale to remove the padding down to the error bar:
ggplot(df, aes(x = name, y = val, fill = name)) +
geom_bar(stat = "identity") +
geom_errorbar(aes(ymin = val - 10,
ymax = val + 10)) +
scale_y_continuous(expand = c(0,0))
Or you can use coord_cartesian to give a hard cutoff:
ggplot(df, aes(x = name, y = val, fill = name)) +
geom_bar(stat = "identity") +
geom_errorbar(aes(ymin = val - 10,
ymax = val + 10)) +
scale_y_continuous(expand = c(0,0)) +
coord_cartesian(ylim = c(0, max(df$val) + 10))