I am trying to plot a loglog graph but use the non-log labels. So instead of showing in x axis 1 (log10(10), it shows 10. I found the following solution. But that's too much work in my opinion. Is there anything equivalent to the Matlab function "loglog"?
plot(log10(x),log10(y),xaxt = "n")
axis(1,at = c(log10(0.5), log10(10), log10(45),log(100)), labels = c(0.5,10,45,100))
Could be done easily with ggplot:
library(ggplot2)
library(scales)
library(tibble)
tibble(
x = seq(1, 10, .01),
y = sin(log(x)*pi) + 2
) %>%
ggplot(aes(x,y)) +
geom_line() +
scale_x_continuous(trans = log_trans()) +
scale_y_continuous(trans = log_trans())
# Or for log10 it can be done without trans:
tibble(
x = seq(1, 10, .01),
y = sin(log(x)*pi) + 2
) %>%
ggplot(aes(x,y)) +
geom_line() +
scale_x_log10() +
scale_y_log10()
Created on 2022-03-09 by the reprex package (v2.0.1)
Related
I would like to display only the minimum number of decimal places in my ggplot axis labels (e.g. 0.1 with 10 as opposed to 10.0. I was trying to get scales::label_number() to do this, but the accuracy argument is applied across all of the labels. Also I'd like to be able to add big.mark = "," if possible.
The closest answer I found suggests an ifelse function to dynamically round as needed but it feels a little clunky. Is there some slick way to do this with {scales} or similar?
Minimal example with current and desired results:
library(tidyverse)
library(scales)
# current labels with scales::label_number()
tibble(x = -2:3, y = 10^x) %>%
ggplot(aes(x, y)) +
geom_point() +
ggtitle("Undesriable: same precision on all labels") +
scale_y_log10(labels = label_number(big.mark = ","), breaks = 10^(-2:3))
# desired labels manually specified
tibble(x = -2:3, y = 10^x) %>%
ggplot(aes(x, y)) +
geom_point() +
ggtitle("Desriable: minimum needed precision on each label with comma") +
scale_y_log10(labels = c(0.01, 0.1, 1, 10, 100, "1,000"), breaks = 10^(-2:3))
Created on 2022-06-23 by the reprex package (v2.0.1)
Using I seems pretty neat to me:
tibble(x = -2:3, y = 10^x) %>%
ggplot(aes(x, y)) +
geom_point() +
scale_y_log10(labels = I, breaks = 10^(-2:3))
Though if you wanted a bit more control, then you could use prettyNum - e.g.
tibble(x = -2:3, y = 10^x) %>%
ggplot(aes(x, y)) +
geom_point() +
scale_y_log10(labels = ~ prettyNum(.x, big.mark = ","), breaks = 10^(-2:3))
In the following plot, which is a simple scatter plot + theme_apa(), I would like that both axes go through 0.
I tried some of the solutions proposed in the answers to similar questions to that but none of them worked.
A MWE to reproduce the plot:
library(papaja)
library(ggplot2)
library(MASS)
plot_two_factor <- function(factor_sol, groups) {
the_df <- as.data.frame(factor_sol)
the_df$groups <- groups
p1 <- ggplot(data = the_df, aes(x = MR1, y = MR2, color = groups)) +
geom_point() + theme_apa()
}
set.seed(131340)
n <- 30
group1 <- mvrnorm(n, mu=c(0,0.6), Sigma = diag(c(0.01,0.01)))
group2 <- mvrnorm(n, mu=c(0.6,0), Sigma = diag(c(0.01,0.01)))
factor_sol <- rbind(group1, group2)
colnames(factor_sol) <- c("MR1", "MR2")
groups <- as.factor(rep(c(1,2), each = n))
print(plot_two_factor(factor_sol, groups))
The papaja package can be installed via
devtools::install_github("crsh/papaja")
What you request cannot be achieved in ggplot2 and for a good reason, if you include axis and tick labels within the plotting area they will sooner or later overlap with points or lines representing data. I used #phiggins and #Job Nmadu answers as a starting point. I changed the order of the geoms to make sure the "data" are plotted on top of the axes. I changed the theme to theme_minimal() so that axes are not drawn outside the plotting area. I modified the offsets used for the data to better demonstrate how the code works.
library(ggplot2)
iris %>%
ggplot(aes(Sepal.Length - 5, Sepal.Width - 2, col = Species)) +
geom_hline(yintercept = 0) +
geom_vline(xintercept = 0) +
geom_point() +
theme_minimal()
This gets as close as possible to answering the question using ggplot2.
Using package 'ggpmisc' we can slightly simplify the code.
library(ggpmisc)
iris %>%
ggplot(aes(Sepal.Length - 5, Sepal.Width - 2, col = Species)) +
geom_quadrant_lines(linetype = "solid") +
geom_point() +
theme_minimal()
This code produces exactly the same plot as shown above.
If you want to always have the origin centered, i.e., symmetrical plus and minus limits in the plots irrespective of the data range, then package 'ggpmisc' provides a simple solution with function symmetric_limits(). This is how quadrant plots for gene expression and similar bidirectional responses are usually drawn.
iris %>%
ggplot(aes(Sepal.Length - 5, Sepal.Width - 2, col = Species)) +
geom_quadrant_lines(linetype = "solid") +
geom_point() +
scale_x_continuous(limits = symmetric_limits) +
scale_y_continuous(limits = symmetric_limits) +
theme_minimal()
The grid can be removed from the plotting area by adding + theme(panel.grid = element_blank()) after theme_minimal() to any of the three examples.
Loading 'ggpmisc' just for function symmetric_limits() is overkill, so here I show its definition, which is extremely simple:
symmetric_limits <- function (x)
{
max <- max(abs(x))
c(-max, max)
}
For the record, the following also works as above.
iris %>%
ggplot(aes(Sepal.Length-6.2, Sepal.Width-3.2, col = Species)) +
geom_point() +
geom_hline(yintercept = 0) +
geom_vline(xintercept = 0)
Setting xlim and slim should work.
library(tidyverse)
# default
iris %>%
ggplot(aes(Sepal.Length, Sepal.Width, col = Species)) +
geom_point()
# setting xlim and ylim
iris %>%
ggplot(aes(Sepal.Length, Sepal.Width, col = Species)) +
geom_point() +
xlim(c(0,8)) +
ylim(c(0,4.5))
Created on 2020-06-12 by the reprex package (v0.3.0)
While the question is not very clear, PoGibas seems to think that this is what the OP wanted.
library(tidyverse)
# default
iris %>%
ggplot(aes(Sepal.Length-6.2, Sepal.Width-3.2, col = Species)) +
geom_point() +
xlim(c(-2.5,2.5)) +
ylim(c(-1.5,1.5)) +
geom_hline(yintercept = 0) +
geom_vline(xintercept = 0)
Created on 2020-06-12 by the reprex package (v0.3.0)
I'm attempting to have a two-line y-axis label that contains a superscript in ggplot and I am struggling.
I want the y axis label to say “[3H]ASEM binding (pmol/g)” with the 3 superscripted and (pmol/g) on a separate line.
This is what I have tried so far:
labs(x="", y=expression(paste("[" ^3 "H] ASEM Binding \n (pmol/g)")))
And it's given me the error "unexpected string constant"
Any suggestions?
You need an empty ''(2 single quotes) prior to the ^3.
ggplot(sample_data, aes(x, y)) +
geom_point() +
labs(
x = "",
y = expression(atop(paste("[", ''^3, "H] ASEM Binding"), "(pmol/g)"))
)
Another alternative is:
y = expression(atop("["^3*"H] ASEM Binding", "(pmol/g)"))
I'm not quite sure what you're doing with your for loop, but this code chunk should get you the two-lined axis label with a superscript for which you are looking.
library(tidyverse)
sample_data <- tibble(x = rnorm(1000),
y = x^2)
sample_data %>%
ggplot(aes(x, y)) +
geom_point() +
labs(
x = "X",
y = expression(atop("Variable", X^2))
)
Is this what you are after?
library(ggplot2)
ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
geom_point()+
labs(x = "",
y = expression(atop("[ "^3*H~"] ASEM Binding", "(pmol/g)")))+
theme(plot.margin = unit(c(10, 10, 20, 10), "mm"))
Created on 2020-05-19 by the reprex package (v0.3.0)
So I'm making a histogram of the months, but the x-axis goes from 0.5 to 12.5. Does anyone know how I can fix this to 1 - 12 (as they represent the months?
x<-c(1,2,3,4,5,6,6,7,8,9,10,11,12)
qplot(x,geom='histogram',fill=I("red"), col=I("darkred"),xlab="Maand",ylab="Hoeveelheid",bins=12)
You can pass x as.factor.
library(ggplot2)
x <- c(1,2,3,4,5,6,6,7,8,9,10,11,12)
x <- as.data.frame(x)
ggplot(x, aes(as.factor(x))) +
geom_bar(fill = "red", color = "darkred") +
xlab("Maand") +
ylab("Hoeveelheid")
You can try
library(tidyverse)
tibble(x = c(1,2,3,4,5,6,6,7,8,9,10,11,12)) %>%
ggplot(aes(x)) +
geom_histogram(binwidth = 1, color="white") +
scale_x_continuous(breaks = 1:12)
In base R you can try
hist(c(1,2,3,4,5,6,6,7,8,9,10,11,12))
I'm learning to use ggplot2 and am looking for the smallest ggplot2 code that reproduces the base::plot result below. I've tried a few things and they all ended up being horrendously long, so I'm looking for the smallest expression and ideally would like to have the dates on the x-axis (which are not there in the plot below).
df = data.frame(date = c(20121201, 20121220, 20130101, 20130115, 20130201),
val = c(10, 5, 8, 20, 4))
plot(cumsum(rowsum(df$val, df$date)), type = "l")
Try this:
ggplot(df, aes(x=1:5, y=cumsum(val))) + geom_line() + geom_point()
Just remove geom_point() if you don't want it.
Edit: Since you require to plot the data as such with x labels are dates, you can plot with x=1:5 and use scale_x_discrete to set labels a new data.frame. Taking df:
ggplot(data = df, aes(x = 1:5, y = cumsum(val))) + geom_line() +
geom_point() + theme(axis.text.x = element_text(angle=90, hjust = 1)) +
scale_x_discrete(labels = df$date) + xlab("Date")
Since you say you'll have more than 1 val for "date", you can aggregate them first using plyr, for example.
require(plyr)
dd <- ddply(df, .(date), summarise, val = sum(val))
Then you can proceed with the same command by replacing x = 1:5 with x = seq_len(nrow(dd)).
After a couple of years, I've settled on doing:
ggplot(df, aes(as.Date(as.character(date), '%Y%m%d'), cumsum(val))) + geom_line()
Jan Boyer seems to have found a more concise solution to this problem in this question, which I have shortened a bit and combined with the answers of Prradep, so as to provide a (hopefully) up-to-date-answer:
ggplot(data = df,
aes(x=date)) +
geom_col(aes(y=value)) +
geom_line(aes(x = date, y = cumsum((value))/5, group = 1), inherit.aes = FALSE) +
ylab("Value") +
theme(axis.text.x = element_text(angle=90, hjust = 1))
Note that date is not in Date-Format, but character, and that value is already grouped as suggested by Prradep in his answer above.