I am trying to plot the following vector using ggplot:
library(ggplot2)
vec =c(44.55 ,47.81 ,40.28 ,44.32 ,53.57 ,45.68 ,52.02 ,44.27 ,33.44 ,41.16)
by = c("1994-04-30", "1994-05-31", "1994-06-30", "1994-07-31", "1994-08-31", "1994-09-30", "1994-10-31", "1994-11-30", "1994-12-31", "1995-01-31")
vec.zoo = zoo(vec, order.by = as.Date(by))
g <-ggplot(vec.zoo) +
geom_line (aes(x=index(vec.zoo), y=coredata(vec.zoo)), color = "cadetblue4", size = 0.6) +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
xlab("Time") +
ylab("Hit Ratio") +
scale_y_continuous(limits = c(0, 100))
scale_x_date(limits = c(start(vec.zoo), end(vec.zoo)))
g
Although I set the limits of the axis, they still don't intersect at origin. I would like to set the intersection at x= 0 and y = start(vec).
Here is the result I obtain:
You may use the expand argument in your scale calls. Setting expand to zero, removes the default, small gap between data and axes (see here)
g <-ggplot(vec.zoo) +
geom_line (aes(x=index(vec.zoo), y=coredata(vec.zoo)), color = "cadetblue4", size = 0.6) +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
xlab("Time") +
ylab("Hit Ratio") +
scale_y_continuous(limits = c(0, 100), expand = c(0, 0)) +
scale_x_date(limits = c(start(vec.zoo), end(vec.zoo)), expand = c(0, 0))
g
Related
I'd like to map different variables for the x axis, y-axis, height of the ridges and gradient fill of the plot along the y-axis.
How can I reconfigure the below code such that the "fill" works with a different variable than that specified by x?
# Example for `geom_density_ridges_gradient()`
ggplot(lincoln_weather, aes(x = `Mean Temperature [F]`, y = `Month`, fill = stat(x))) +
geom_density_ridges_gradient(scale = 3, rel_min_height = 0.01) +
scale_x_continuous(expand = c(0, 0)) +
scale_y_discrete(expand = c(0, 0)) +
scale_fill_viridis_c(name = "Temp. [F]", option = "C") +
coord_cartesian(clip = "off") +
labs(title = 'Temperatures in Lincoln NE in 2016') +
theme_ridges(font_size = 13, grid = TRUE) +
theme(axis.title.y = element_blank())
I was curious if anyone knew how to create a heatmap with an isoquant curve that identifies all x and y combinations whose product equals a certain constant. The final product should look like the following picture:
Scatterplot with isoquant curve
Here is the code I use to generate my plot, but as of right now I can't get the curve in the plot as depicted in the picture above:
vs.vpd.by.drop_days <- ggplot(event_drops, aes(vs, vpd)) +
geom_point(aes(color = day_since), size = 2, alpha = 0.2) +
scale_color_gradientn(colors = c("darkblue","green","yellow","red"),
breaks = c(0,25,50,75),
limits = c(0,75),
name = "Days since \n first drop") +
ggtitle("Drops by VPD and Wind Speed") +
theme(plot.title = element_text(size = 18, face = "bold", hjust = 0.5),
axis.title = element_text(size = 15)) +
xlab(label = "Wind Speed (mph)") +
ylab(label = "Vapor Pressure Deficit") +
expand_limits(x = 0, y = 0) +
scale_x_continuous(expand = c(0, 0), limits = c(0,20)) +
scale_y_continuous(expand = c(0, 0), limits = c(0,5))
vs.vpd.by.drop_days
One option to achieve that would be geom_function.
Using mtcars as example data:
library(ggplot2)
ggplot(mtcars, aes(hp, mpg, color = disp)) +
geom_point() +
geom_function(fun = function(x) 3000 / x)
I'm having a hard time dealing with this plot.
The height of values in ANI>96 making it hard to read the red and blue percentage text.
I failed to break the y-axis by looking at answers from other posts in StackOverflow.
Any suggestions?
Thanks.
library(data.table)
library(ggplot2)
dt <- data.table("ANI"= sort(c(seq(79,99),seq(79,99))), "n_pairs" = c(5, 55, 13, 4366, 6692, 59568, 382873, 397996, 1104955, 282915,
759579, 261170, 312989, 48423, 120574, 187685, 353819, 79468, 218039, 66314, 41826, 57668, 112960, 81652, 28613,
64656, 21939, 113656, 170578, 238967, 610234, 231853, 1412303, 5567, 4607268, 5, 14631942, 0, 17054678, 0, 3503846, 0),
"same/diff" = rep(c("yes","no"), 21))
for (i in 1:nrow(dt)) {
if (i%%2==0) {
next
}
total <- dt$n_pairs[i] + dt$n_pairs[i+1]
dt$total[i] <- total
dt$percent[i] <- paste0(round(dt$n_pairs[i]/total *100,2), "%")
dt$total[i+1] <- total
dt$percent[i+1] <- paste0(round(dt$n_pairs[i+1]/total *100,2), "%")
}
ggplot(data=dt, aes(x=ANI, y=n_pairs, fill=`same/diff`)) +
geom_text(aes(label=percent), position=position_dodge(width=0.9), hjust=0.75, vjust=-0.25) +
geom_bar(stat="identity") + scale_x_continuous(breaks = dt$ANI) +
labs(x ="ANI", y = "Number of pairs", fill = "Share one common species taxonomy?") +
theme_classic() + theme(legend.position="bottom")
Here is the list of major changes I made:
I reduced the y axis by zooming into the chart with coord_cartesian (which is called by coord_flip).
coord_flip shouuld also improve the readability of the chart by switching x and y. I don't know if the switch is a desirable output for you.
Also now position_dodge, works as expected: two bars next to each other with the labels on top (on the left in this case).
I set geom_bar before geom_text so that the text is always in front of the bars in the chart.
I set scale_y_continuous to change the labels of the y axis (in the chart the x axis because of the switch) to improve the readability of the zeros.
ggplot(data=dt, aes(x = ANI, y = n_pairs, fill = `same/diff`)) +
geom_bar(stat = "identity", position = position_dodge2(width = 1), width = 0.8) +
geom_text(aes(label = percent), position = position_dodge2(width = 1), hjust = 0, size = 3) +
scale_x_continuous(breaks = dt$ANI) +
scale_y_continuous(labels = scales::comma) +
labs(x ="ANI", y = "Number of pairs", fill = "Share one common species taxonomy?") +
theme_classic() +
theme(legend.position = "bottom") +
coord_flip(ylim = c(0, 2e6))
EDIT
Like this columns and labels are stacked but labels never overlap.
ggplot(data=dt, aes(x = ANI, y = n_pairs, fill = `same/diff`)) +
geom_bar(stat = "identity", width = 0.8) +
geom_text(aes(label = percent,
hjust = ifelse(`same/diff` == "yes", 1, 0)),
position = "stack", size = 3) +
scale_x_continuous(breaks = dt$ANI) +
scale_y_continuous(labels = scales::comma) +
labs(x ="ANI", y = "Number of pairs", fill = "Share one common species taxonomy?") +
theme_classic() +
theme(legend.position = "bottom") +
coord_flip(ylim = c(0, 2e6))
Alternatively, you can avoid labels overlapping with check_overlap = TRUE, but sometimes one of the labels will not be shown.
ggplot(data=dt, aes(x = ANI, y = n_pairs, fill = `same/diff`)) +
geom_bar(stat = "identity", width = 0.8) +
geom_text(aes(label = percent), hjust = 1, position = "stack", size = 3, check_overlap = TRUE) +
scale_x_continuous(breaks = dt$ANI) +
scale_y_continuous(labels = scales::comma) +
labs(x ="ANI", y = "Number of pairs", fill = "Share one common species taxonomy?") +
theme_classic() +
theme(legend.position = "bottom") +
coord_flip(ylim = c(0, 2e6))
I'm trying to remove some space in my plot, but when I use ylim I got the following warning:
Warning message: Removed 2 rows containing missing values (geom_text).
Then I lost some data.
Here is my code:
ggplot(data_se5) +
geom_bar(data=data_se5, aes(x = SEM_PRI, y = acumobito,#color = "Número de internações acumuladas",
fill = CLASSI_FIN,
group=CLASSI_FIN),color="transparent",stat="identity") +
theme(text = element_text(size=20), legend.position="none") + #re
annotate("text", x = 1:25, y=cumsum(aggregate(obito ~ SEM_PRI, dadoscovid2, sum)$obito) + 2,
vjust = -.8, label = sort(data_se5[data_se5$CLASSI_FIN=="SRAG",]$acumobito), colour = "gold4")+
annotate("text", x = data_se5[data_se5$CLASSI_FIN=="SRAG-não",]$SEM_PRI, y=data_se5[data_se5$CLASSI_FIN=="SRAG-não",]$acumobito/2-15,
vjust = -.8, label = data_se5[data_se5$CLASSI_FIN=="SRAG-não",]$acumobito, colour = "black")+
scale_x_continuous(breaks = 1:25,labels = labelss) +
scale_colour_manual("",values= c("Número de internações acumuladas" = "gold"))+
scale_fill_manual("","Número de internações acumuladas", values = c("gold","dodgerblue3"))+
labs(x="Semana Epidemiológica")+ylab("") + theme_bw(base_size = 20)+ylab(NULL)+ylim(-15, max(data_se5$acumtotal)+10)+
theme(legend.position = "bottom", legend.direction = "horizontal",axis.text.y = element_blank())
And here I paint with red the parts that I'd like to exclude.
Any hint on how can I do that?
By default ggplot2 expands the axis for continuous scales by 5 percent on each side and by 0.6 units on each side for discrete scales. To remove or reduce the expansion you can use the expand argument in the scale like so:
library(ggplot2)
# Default
ggplot(mtcars, aes(factor(cyl))) +
geom_bar()
# Remove expansion
ggplot(mtcars, aes(factor(cyl))) +
geom_bar() +
scale_x_discrete(expand = expansion(add = c(0, 0))) +
scale_y_continuous(expand = expansion(mult = c(0, 0)))
I'm plotting some graphs to introduce the concept of mathematical function to highschool students. Right now, I'd like to give them an example of what is NOT a function, by plotting an horizontal parabola:
x <- seq(from = -3, to = 3, by = 0.001)
y <- -x^2 + 5
grafico <- ggplot()+
geom_hline(yintercept = 0)+
geom_vline(xintercept = 0)+
geom_line(mapping = aes(x = x, y = y),color="darkred",size=1)+
theme_light()+
xlab("")+
ylab("")+
scale_x_continuous(breaks = seq(from = -100, to = 100, by = 1))+
scale_y_continuous(breaks = seq(from = -100, to = 100, by = 1))+
coord_flip(ylim = c(-1.5,5.5), xlim = c(-3,3),expand = FALSE)
print(grafico)
Which outputs the following image:
This is quite close to what I want, but I would like both axes' scales to match, to keep things simple for the students. For this, I'd tried using coord_equal, but unluckily, it seems to cancel coord_flip's effects:
x <- seq(from = -3, to = 3, by = 0.001)
y <- -x^2 + 5
grafico <- ggplot()+
geom_hline(yintercept = 0)+
geom_vline(xintercept = 0)+
geom_line(mapping = aes(x = x, y = y),color="darkred",size=1)+
theme_light()+
xlab("")+
ylab("")+
scale_x_continuous(breaks = seq(from = -100, to = 100, by = 1))+
scale_y_continuous(breaks = seq(from = -100, to = 100, by = 1))+
coord_flip(ylim = c(-1.5,5.5), xlim = c(-3,3),expand = FALSE)+
coord_equal()
print(grafico)
My question is: Is there a simple way to include coord_flip functionality into coord_equal?
For example, I know I can get coord_cartesian functionality by using the parameters ylim and xlim.
Based on your use case, it doesn't look like you really need to flip the coordinates: you can just reverse the order of inputs for x & y, and use geom_path() instead of geom_line() to force the plot to follow the order in your inputs.
The ggplot help file states:
geom_path() connects the observations in the order in which they
appear in the data. geom_line() connects them in order of the
variable on the x axis.
ggplot() +
geom_hline(yintercept = 0) +
geom_vline(xintercept = 0) +
geom_path(mapping = aes(x = y, y = x), color="darkred", size = 1) + # switch x & y here
theme_light() +
xlab("") +
ylab("") +
scale_x_continuous(breaks = seq(from = -100, to = 100, by = 1)) +
scale_y_continuous(breaks = seq(from = -100, to = 100, by = 1)) +
coord_equal(xlim = c(-1.5, 5.5), ylim = c(-3, 3), expand = FALSE) # switch x & y here