How to x and y range the same in log scale? - r

library(ggplot2)
f=data.frame(x=exp(rnorm(100)), y=exp(rnorm(100, sd=2)))
ggplot(f, aes(x=x, y=y)) + geom_point() + coord_fixed() + scale_x_log10() + scale_y_log10()
The ranges of x and y are not the same. How can I make the ranges be the same for x and y while showing all the points?

You can set limits in both of your log scales like this:
library(ggplot2)
f=data.frame(x=exp(rnorm(100)), y=exp(rnorm(100, sd=2)))
ggplot(f, aes(x=x, y=y)) +
geom_point() + coord_fixed() +
scale_x_log10(limits = c(0.1, 10)) +
scale_y_log10(limits = c(0.1, 10))
Created on 2023-01-20 with reprex v2.0.2

Related

Error with tick marks interval and density curve in ggplot2 [duplicate]

This question already has answers here:
geom_bar bars not displaying when specifying ylim
(4 answers)
R - ggplot2: geom_area loses its fill if limits are defined to max and min values from a data.frame
(1 answer)
Closed 6 days ago.
I am using ggplot2 to draw a line chart with the following R codes:
library(ggplot2)
X <-c(0, 1, 2, 3, 4, 5)
Y <-c(1, 2, 3, 2, 1, 2)
df <- data.frame(X=X, Y=Y)
ggplot(data=df, mapping=aes(x=X, y=Y))+
geom_line(colour="violet", size=3, linetype=2)+
geom_point(shape=23, fill="blue", color="darkred", size=3)
and the output is fine like this:
However, I would like to color the under density curve and I change the codes like these:
ggplot(data=df, mapping=aes(x=X, y=Y))+geom_line(colour="violet", size=3, linetype=2)+geom_point(shape=23, fill="blue", color="darkred", size=3)+geom_area("darkseagreen1")
and I got output like this:
This is not ideal so I try to set the tick marks interval using the following code:
ggplot(data=df, mapping=aes(x=X, y=Y))+geom_line(colour="violet", size=3, linetype=2)+geom_point(shape=23, fill="blue", color="darkred", size=3)+geom_area(fill = "darkseagreen1")+scale_y_continuous(breaks = seq(71.4, 72.9, by=0.3), limits=c(71.4,72.7))
It becomes normal but the color is gone like this:
Can anyone help me with this error? Thank you.
You can use geom_area() if you set your limits using coord_cartesian() (see e.g. https://stackoverflow.com/a/3606798/12957340 for more details).
For example:
library(ggplot2)
X <-c(0, 1, 2, 3, 4, 5)
Y <-c(1, 2, 3, 2, 1, 2)
df <- data.frame(X=X, Y=Y)
# starting plot
ggplot(data=df, mapping=aes(x=X, y=Y)) +
geom_line(colour="violet", size=3, linetype=2) +
geom_point(shape=23, fill="blue", color="darkred", size=3)
#> Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
#> ℹ Please use `linewidth` instead.
ggsave("example.pdf")
#> Saving 7 x 5 in image
# with geom_area()
ggplot(data=df, mapping=aes(x=X, y=Y)) +
geom_line(colour="violet", size=3, linetype=2) +
geom_point(shape=23, fill="blue", color="darkred", size=3) +
geom_area(fill = "darkseagreen1")
ggsave("example2.pdf")
#> Saving 7 x 5 in image
# add y-axis limits (the problem)
ggplot(data=df, mapping=aes(x=X, y=Y)) +
geom_line(colour="violet", size=3, linetype=2) +
geom_point(shape=23, fill="blue", color="darkred", size=3) +
geom_area(fill = "darkseagreen1") +
scale_y_continuous(breaks = seq(0, 3, by=0.3), limits = c(1, 2))
ggsave("example3.pdf")
#> Saving 7 x 5 in image
# add y-axis limits without losing data (a solution)
ggplot(data=df, mapping=aes(x=X, y=Y)) +
geom_line(colour="violet", size=3, linetype=2) +
geom_point(shape=23, fill="blue", color="darkred", size=3) +
geom_area(fill = "darkseagreen1") +
scale_y_continuous(breaks = seq(0, 3, by=0.3)) +
coord_cartesian(ylim = c(1,2))
ggsave("example4.pdf")
#> Saving 7 x 5 in image
Created on 2023-02-08 with reprex v2.0.2
You want to use geom_ribbon() instead of geom_area(). Try this code instead:
ggplot(data = df, mapping = aes(x = X, y = Y)) +
geom_line(colour = "violet", size = 3, linetype = 2) +
geom_point(shape = 23, fill = "blue", color = "darkred", size = 3) +
scale_y_continuous(breaks = seq(71.4, 72.9, by = 0.3), limits = c(71.4, 72.7)) +
geom_ribbon(aes(ymin = 71.4, ymax = Y), fill = "darkseagreen1")

R studio add geom_abline with specified intercept

I want to have a line that crosses the chart at 45 degrees no matter what the x and y scale is. In this example the intercept for the abline shoud be around x=-3 and y=-0.5.
Below a few line of code:
x <- seq(1,10,1)
y <- sample(1:100, 10, replace=T)
df <- data.frame(x,y)
ggplot(df, aes(x=x, y=y)) +
geom_point() +
geom_abline(slope = 45) +
scale_y_continuous(breaks = scales::pretty_breaks(n = 10), limits = c(-10,10)) +
scale_x_continuous(breaks = scales::pretty_breaks(n = 10), limits = c(-2,10))
You would just add
ggplot2::annotation_custom(grid::linesGrob())
to your plot.
So you can do this:
x <- rnorm(100)
y <- rnorm(100)
df <- data.frame(x,y)
ggplot(df, aes(x=x, y=y)) +
geom_point() +
ggplot2::annotation_custom(grid::linesGrob())
or this
ggplot(df, aes(x=x)) +
geom_histogram() +
ggplot2::annotation_custom(grid::linesGrob())
If you want to change the look of the line you need to change the grob:
ggplot(df, aes(x=x, y=y)) +
geom_point() +
ggplot2::annotation_custom(grid::linesGrob(gp = grid::gpar(col = "red", lty = 2)))

How to overlay geom_bar and geom_line plots with different number of elements using ggplot2?

Assuming I have two data.frames with different data but in the same range of x-values
a <-data.frame(x=c(1,1,1,2,2,2,3,3,3),
y=c(0.3,0.4,0.3,0.2,0.5,0.3,0.4,0.4,0.2),
z=c("do","re","mi","do","re","mi","do","re","mi"))
b <- data.frame(x=c(1,2,3),y=c(10,15,8))
Both, a and b have the same range of X values (1,2,3) but while a is a data.frame with 9 rows, b is a data.frame with 3 rows.
I use geom_bar in order to plot the distribution of values of a, like this:
ggplot(a, aes(x=x, y=y, fill=z)) +
geom_bar(position="stack",stat="identity") +
ylab("") +
xlab("x")
And I use geom_line to plot b data, like this:
ggplot(b, aes(x=x, y=y)) +
geom_line(stat="identity") +
ylab("") + xlab("x") + ylim(0,15)
Now I would like to overlay this geom_line plot to the previous geom_bar plot. My first try was to do the following:
ggplot(a, aes(x=x, y=y, fill=z)) +
geom_bar(position="stack",stat="identity") +
ylab("") + xlab("x") +
ggplot(b, aes(x=x, y=y)) +
geom_line(stat="identity") +
ylab("") + xlab("x") + ylim(0,15)
With no success.
How can I overlay a geom_line plot to a geom_bar plot?
Try this
p <- ggplot()
p <- p + geom_bar(data = a, aes(x=x, y=y, fill=z), position="stack",stat="identity")
p <- p + geom_line(data = b, aes(x=x, y=y/max(y)), stat="identity")
p
Update:
You can rescale the one y to make them the same. As I don't know the relations between the two ys, I rescaled them by using y/max(y). Does this solve you problem?
Try merging the datasets first, then plotting, like this:
require(ggplot2)
df <- merge(a,b,by="x")
ggplot(df, aes(x=x, y=y.x, fill=z)) +
geom_bar(position="stack",stat="identity") +
geom_line(aes(x=x, y=y.y)) +
ylab("") + xlab("x")
Output:
I edited the sample data to better illustrate the effects, because the y-axis scaling of the original data would not have matched well:
a <-data.frame(x=c(1,1,1,2,2,2,3,3,3),
y=c(0.3,0.4,0.3,0.2,0.5,0.3,0.4,0.4,0.2),
z=c("do","re","mi","do","re","mi","do","re","mi"))
b <- data.frame(x=c(1,2,3),y=c(.4,1,.4))

How do i create a timestamp on my histogram using ggplot where time is not plotted on either axis

I would like to create a timestamp on my histogram on mtcars dataset where I am plotting the frequency of mileage.
library(ggplot2)
ggplot(mtcars, aes(x=mpg, fill="red")) + geom_histogram(bins = 30) +
geom_vline(aes(xintercept=mean(mpg)),color="blue", linetype="dashed",
size=1) +theme(legend.position="top")
Like this?
ggplot(mtcars, aes(x=mpg, fill="red")) + geom_histogram(bins = 30) +
geom_vline(aes(xintercept=mean(mpg)),color="blue", linetype="dashed",
size=1) +theme(legend.position="top") +
annotate("text", x = 30, y = 4, label = Sys.time())

Draw lines between two facets in ggplot2

How can I draw several lines between two facets?
I attempted this by plotting points at the min value of the top graph but they are not between the two facets. See picture below.
This is my code so far:
t <- seq(1:1000)
y1 <- rexp(1000)
y2 <- cumsum(y1)
z <- rep(NA, length(t))
z[100:200] <- 1
df <- data.frame(t=t, values=c(y2,y1), type=rep(c("Bytes","Changes"), each=1000))
points <- data.frame(x=c(10:200,300:350), y=min(y2), type=rep("Bytes",242))
vline.data <- data.frame(type = c("Bytes","Bytes","Changes","Changes"), vl=c(1,5,20,5))
g <- ggplot(data=df, aes(x=t, y=values)) +
geom_line(colour=I("black")) +
facet_grid(type ~ ., scales="free") +
scale_y_continuous(trans="log10") +
ylab("Log values") +
theme(axis.text.x = element_text(angle = 90, hjust = 1), panel.margin = unit(0, "lines"))+
geom_point(data=points, aes(x = x, y = y), colour="green")
g
In order to achieve that, you have to set the margins inside the plot to zero. You can do that with expand=c(0,0). The changes I made to your code:
When you use scale_y_continuous, you can define the axis label inside that part and you don't need a seperarate ylab.
Changed colour=I("black") to colour="black" inside geom_line.
Added expand=c(0,0) to scale_x_continuous and scale_y_continuous.
The complete code:
ggplot(data=df, aes(x=t, y=values)) +
geom_line(colour="black") +
geom_point(data=points, aes(x = x, y = y), colour="green") +
facet_grid(type ~ ., scales="free") +
scale_x_continuous("t", expand=c(0,0)) +
scale_y_continuous("Log values", trans="log10", expand=c(0,0)) +
theme(axis.text.x=element_text(angle=90, vjust=0.5), panel.margin=unit(0, "lines"))
which gives:
Adding lines can also be done with geom_segment. Normally the lines (segments) will appear in both facets. If you want them to appear between the two facets, you will have to restrict that in data parameter:
ggplot(data=df, aes(x=t, y=values)) +
geom_line(colour="black") +
geom_segment(data=df[df$type=="Bytes",], aes(x=10, y=0, xend=200, yend=0), colour="green", size=2) +
geom_segment(data=df[df$type=="Bytes",], aes(x=300, y=0, xend=350, yend=0), colour="green", size=1) +
facet_grid(type ~ ., scales="free") +
scale_x_continuous("t", expand=c(0,0)) +
scale_y_continuous("Log values", trans="log10", expand=c(0,0)) +
theme(axis.text.x=element_text(angle=90, vjust=0.5), panel.margin=unit(0, "lines"))
which gives:

Resources