I want to define what is written on the ticks of the y-axis in a ggplot plot.
The particular problem is that I want the y-axis to show one decimal point. Instead of 25 it should read 25.0. I can of course hard-code it in by hand; but this is extremely tedious. (The code below does what it is supposed to do)
library(ggplot2)
DF <- data.frame(c(0:100),c(0:100)) colnames(DF)=c("x","y")
pl <- ggplot(data = DF, aes(x = x, y = y)) + geom_point() +
scale_y_continuous(breaks = c(0,25.0,50.0,75.0,100.0),
labels = c("0","25.0","50.0","75.0","100.0"))
Is there a way to format the x and y axis without having to type the exact labels in myself?
Instead of labels = c("0","25.0","50.0","75.0","100.0") there should be a command that whatever the ticks on the y-axis, the labeling should be done with one digit after the decimal point.
How about:
pl <- ggplot(data = DF, aes(x = x, y = y)) +
geom_point() +
scale_y_continuous(labels = function(x) format(x, nsmall = 1))
Try format:
pl <- ggplot(data = DF, aes(x = x, y = y)) + geom_point() +
scale_y_continuous(breaks = c(0,25.0,50.0,75.0,100.0),
labels = format(c("0","25","50","75","100"),nsmall=1))
Related
I am producing a ggplot which looks at a curve in a dataset. When I build the plot, ggplot is automatically adding fill to data which is on the negative side of the x axis. Script and plot shown below.
ggplot(df, aes(x = Var1, y = Var2)) +
geom_line() +
geom_vline(xintercept = 0) +
geom_hline(yintercept = Var2[1])
Using base R, I am able to get the plot shown below which is how it should look.
plot(x = df$Var1, y = df$Var2, type = "l",
xlab = "Var1", ylab = "Var2")
abline(v = 0)
abline(h = df$Var2[1])
If anyone could help identify why I might be getting the automatic fill and how I could make it stop, I would be very appreciative. I would like to make this work in ggplot so I can later animate the line as it is a time series that can be used to compare between other datasets from the same source.
Can add data if necessary. Data set is 1561 obs long however. Thanks in advance.
I guess you should try
ggplot(df, aes(x = Var1, y = Var2)) +
geom_path() +
geom_vline(xintercept = 0) +
geom_hline(yintercept = Var2[1])
instead. The geom_line()-function connects the points in order of the variable on the x-axis.
Take a look at this example
dt <- data.frame(
x = c(seq(-pi/2,3*pi,0.001),seq(-pi/2,3*pi,0.001)),
y = c(sin(seq(-pi/2,3*pi,0.001)), cos(seq(-pi/2,3*pi,0.001)))
)
ggplot(dt, aes(x,y)) + geom_line()
The two points with x-coordinate -pi/2 will be connected first, creating a vertical black line. Next x = -pi/2 + 0.001 will be processed and so on. The x values will be processed in order.
Therefore you should use geom_path() to get the desired result
dt <- data.frame(
x = c(seq(-pi/2,3*pi,0.001),seq(-pi/2,3*pi,0.001)),
y = c(sin(seq(-pi/2,3*pi,0.001)), cos(seq(-pi/2,3*pi,0.001)))
)
ggplot(dt, aes(x,y)) + geom_path()
I know how to modify titles in ggplot without altering the original data. Suppose I have the following data frame and I want to change the labels. Then, I would do so in the following way
df <- data.frame(x = 1:4, y = 1:4, label = c(c("params[1]", "params[2]", "params[3]",
"params[4]")))
params_names <- list(
'params[1]'= "beta[11]",
'params[2]'= "beta[22]",
'params[3]'= "beta[33]",
'params[4]'= "beta[44]"
)
param_labeller <- function(variable, value){
params_names[value]
}
ggplot(df, aes(x=x,y=y)) +
geom_point() +
facet_grid(~label, labeller = param_labeller)
If I wanted to display the subscripts, I would just do this
ggplot(df, aes(x=x,y=y)) +
geom_point() +
facet_grid(~label, labeller = label_parsed)
How do I apply both operations at the same time?
I don't know exactly if this conflicts with you not wanting to "alter" the original data, but you add the labelling information to the factor itself:
df$label2 <- factor(df$label,
labels = c("beta[4]", "beta[24]", "beta[42]", "beta[43]"))
ggplot(df, aes(x = x, y = y)) +
geom_point() +
facet_grid( ~ label2, labeller = label_parsed)
This produces the following plot:
Plot with formatted facet labels
I am trying to generate a ternary plot using ggtern.
My data ranges from 0 - 1000 for x, y,and z variables. I wondered if it is possible to extend the axis length above 100 to represent my data.
#Nevrome is on the right path, your points will still be plotted as 'compositions', ie, concentrations sum to unity, but you can change the labels of the axes, to indicate a range from 0 to 1000.
library(ggtern)
set.seed(1)
df = data.frame(x = runif(10)*1000,
y = runif(10)*1000,
z = runif(10)*1000)
breaks = seq(0,1,by=0.2)
ggtern(data = df, aes(x, y, z)) +
geom_point() +
limit_tern(breaks=breaks,labels=1000*breaks)
I think there is no direct solution to do this with ggtern. But an easy workaround could look like this:
library(ggtern)
df = data.frame(x = runif(50)*1000,
y = runif(50)*1000,
z = runif(50)*1000,
Group = as.factor(round(runif(50,1,2))))
ggtern() +
geom_point(data = df, aes(x/10, y/10, z/10, color = Group)) +
labs(x="X", y="Y", z="Z", title="Title") +
scale_T_continuous(breaks = seq(0,1,0.2), labels = 1000*seq(0,1,0.2)) +
scale_L_continuous(breaks = seq(0,1,0.2), labels = 1000*seq(0,1,0.2)) +
scale_R_continuous(breaks = seq(0,1,0.2), labels = 1000*seq(0,1,0.2))
Please pardon my ignorance if this is a simple question, but I can't seem to figure out how to underline any part of a plot title. I'm using ggplot2.
The best I could find was
annotate("segment") done by hand, and I have created a toy plot to illustrate its method.
df <- data.frame(x = 1:10, y = 1:10)
rngx <- 0.5 * range(df$x)[2] # store mid-point of plot based on x-axis value
rngy <- 0.5 * range(df$y)[2] # stores mid-point of y-axis for use in ggplot
ggplot(df, aes(x = x, y = y)) +
geom_point() +
ggtitle("Oh how I wish for ..." ) +
ggplot2::annotate("text", x = rngx, y = max(df$y) + 1, label = "underlining!", color = "red") +
# create underline:
ggplot2::annotate("segment", x = rngx-0.8, xend = rngx + 0.8, y= 10.1, yend=10.1)
uses bquote(underline() with base R
pertains to lines over and under nodes on a graph
uses plotmath and offers a workaround, but it didn't help
Try this:
ggplot(df, aes(x = x, y = y)) + geom_point() +
ggtitle(expression(paste("Oh how I wish for ", underline(underlining))))
Alternatively, as BondedDust points out in the comments, you can avoid the paste() call entirely, but watch out for the for:
ggplot(df, aes(x = x, y = y)) + geom_point() +
ggtitle(expression(Oh~how~I~wish~'for'~underline(underlining)))
Or another, even shorter approach suggested by baptiste that doesn't use expression, paste(), or the many tildes:
ggplot(df, aes(x = x, y = y)) + geom_point() +
ggtitle(~"Oh how I wish for "*underline(underlining))
Im trying to align the x-axes of a bar plot and line plot in one window frame using ggplot. Here is the fake data I'm trying to do it with.
library(ggplot2)
library(gridExtra)
m <- as.data.frame(matrix(0, ncol = 2, nrow = 27))
colnames(m) <- c("x", "y")
for( i in 1:nrow(m))
{
m$x[i] <- i
m$y[i] <- ((i*2) + 3)
}
My_plot <- (ggplot(data = m, aes(x = x, y = y)) + theme_bw())
Line_plot <- My_plot + geom_line()
Bar_plot <- My_plot + geom_bar(stat = "identity")
grid.arrange(Line_plot, Bar_plot)
Thank you for your help.
#eipi10 answers this particular case, but in general you also need to equalize the plot widths. If, for example, the y labels on one of the plots take up more space than on the other, even if you use the same axis on each plot, they will not line up when passed to grid.arrange:
axis <- scale_x_continuous(limits=range(m$x))
Line_plot <- ggplot(data = m, aes(x = x, y = y)) + theme_bw() + axis + geom_line()
m2 <- within(m, y <- y * 1e7)
Bar_plot <- ggplot(data = m2, aes(x = x, y = y)) + theme_bw() + axis + geom_bar(stat = "identity")
grid.arrange(Line_plot, Bar_plot)
In this case, you have to equalize the plot widths:
Line_plot <- ggplot_gtable(ggplot_build(Line_plot))
Bar_plot <- ggplot_gtable(ggplot_build(Bar_plot))
Bar_plot$widths <-Line_plot$widths
grid.arrange(Line_plot, Bar_plot)
The gridlines on the x axes will be aligned if you use scale_x_continuous to force ggplot to use limits you specify.
My_plot <- ggplot(data = m, aes(x = x, y = y)) + theme_bw() +
scale_x_continuous(limits=range(m$x))
Now, when you add the layers, the axes will share the common scaling.