I got the following chart in ggplot:
library(ggplot2)
a <- seq(1,20)
b <- a^0.25
df <- as.data.frame(cbind(a,b))
ggplot(df, aes(x = a, y = b)) + geom_point()
Question: How can I add axes to the top and to the right of the plot, with ticks, but not with labels (as the labels are on the bottom and on the left already), and also with white background? If I use + theme_classic(), the background becomes white, but the axes on the top and right are also removed.
I think you're looking for dup_axis
ggplot(df, aes(x = a, y = b)) +
geom_point() +
scale_x_continuous(sec.axis = dup_axis(name = NULL, labels = NULL)) +
scale_y_continuous(sec.axis = dup_axis(name = NULL, labels = NULL)) +
theme_classic()
EDIT: I wasn't clear on whether you wanted tick labels, you can add them back by removing the labels = NULL
Related
I want a plot with a log scale in x-axis and a "normal" y-axis.
I got a plot but I see a strange thing on my y-axis which I couldnt figure out.
breaks <- 10^(-10:10)
minor_breaks <- rep(1:9, 21)*(10^rep(-10:10, each=9))
ggplot(mtcars, aes(mpg, disp)) +
geom_line(size = 1, color = "blue") +
scale_x_log10(breaks = breaks, minor_breaks = minor_breaks, limits = c(0.1,50)) +
annotation_logticks()
What is this thing on the y-axis and how can I get rid of it?
Using the code below you can remove the black mess on the y-axis because it's the annotated tick marks you've added. Setting side = "b" indicates that you only want the tick marks on the x-axis (the bottom).
breaks <- 10^(-10:10)
minor_breaks <- rep(1:9, 21)*(10^rep(-10:10, each=9))
g <- ggplot(mtcars, aes(mpg, disp)) +
geom_line(size = 1, color = "blue") +
scale_x_log10(breaks = breaks, minor_breaks = minor_breaks, limits = c(0.1,50)) +
annotation_logticks(sides = "b")
g
By default annotation_logticks() adds ticks to the bottom and left axis. You don't want ticks on the left (y-axis) because it isn't log-scaled. That's why it looks wrong.
Use the sides = argument to label only the bottom (x-axis):
g <- ggplot(mtcars, aes(mpg, disp)) +
geom_line(size = 1, color = "blue") +
scale_x_log10(breaks = breaks, minor_breaks = minor_breaks, limits = c(0.1, 50)) +
annotation_logticks(sides = "b")
I prepared a MWE and hope for help on how to set ticks and labels at different position on the x-axis for a grouped bar plot.
library(ggplot2)
library(reshape2)
data <- data.frame(name = c("X","Y","Z"), A = c(2,4,6), B = c(1,3,4), C = c(3,4,5))
data <- melt(data, id = 1)
ggplot(data, aes(name,value)) +
geom_bar(aes(fill = variable), position = "dodge", stat = "identity")
The ticks should appear BETWEEN the groups, but the labels centered below the grouped bars (as they are in the figure). I tried to set user-defined breaks (as factors) for scale_x_discrete but it only made my ticks and labels disappear completely.
Any help is much appreciated!
One options would be to convert the discrete x scale to continuous, to facilitate calculation of break positions:
# numeric version of x values
data$x <- as.integer(as.factor(data$name))
1. x ticks between groups of bars
x_tick <- head(unique(data$x), -1) + 0.5
len <- length(x_tick)
ggplot(data, aes(x = x, y = value, fill = variable)) +
geom_col(position = "dodge") +
scale_x_continuous(breaks = c(sort(unique(data$x)), x_tick),
labels = c(sort(unique(data$name)), rep(c(""), len))) +
theme(axis.ticks.x = element_line(color = c(rep(NA, len + 1), rep("black", len))))
2: x ticks before, between, and after groups of bars
x_tick <- c(0, unique(data$x)) + 0.5
len <- length(x_tick)
ggplot(data, aes(x = x, y = value, fill = variable)) +
geom_col(position = "dodge") +
scale_x_continuous(breaks = c(sort(unique(data$x)), x_tick),
labels = c(sort(unique(data$name)), rep(c(""), len))) +
theme(axis.ticks.x = element_line(color = c(rep(NA, len - 1), rep("black", len))))
Don't ask me about the additional grid lines which appeared at 2.25 and 1.75 respectively...
Here is another solution which uses grid package.
library(grid)
nTicks <- 2
tickersPosition <- unit(rep(1:nTicks /(nTicks+1), each=2), "native")
Part 1:nTicks /(nTicks+1) identifies positions where ticks will be placed.
p1 <- ggplot(data, aes(name,value)) +
geom_bar(aes(fill = variable), position = "dodge", stat = "identity")
To change position of ticks we need to create gtable
p2 <- ggplot_gtable(ggplot_build(p1))
and find the right grob (using str):
p2$grobs[[7]]$children$axis$grobs[[1]]$x <- tickersPosition
After the position is rewritten, we can run
grid::grid.draw(p2)
which will show warnings. This is because of a different number of splits.
I am making a presentation and would like to present one line graph (geom_line()) with an appropriate legend. I then want to overlay a new geom_line and add the corresponding legend item. For aesthetic reasons, I want the overlay to not modify the legend location given in the first plot. The effect should be that one is drawing on an existing graph, and adding to its legend.
If I simply using ggplot to first make the first plot and then make a new plot with both lines, the location of the legend changes noticeably.
If I try to make the first plot be the full plot, but setting one of the line sizes to zero, I run into the problem that I can't suppress the legend-item for the size-zero line.
How can I achieve my desired effect with ggplot2?
EDIT:
Here is the code to make the two graphs that I first naively tried.
require(ggplot2)
require(reshape2)
x<-seq(-10,10,length=200)
G <- (1/(sqrt(2*pi))) * exp(-((x)^2)/(2))
G2 <- 2*(1/(pi))*(1/(x^2+1))
df = data.frame(x,G,G2)
ggplot(data = melt(data.frame(x,G),id.vars = 'x'))+
geom_line(aes(x=x, y=value, color=variable),size=.5)+
scale_color_manual("Distribution",values=c("orange"),labels=c("Gaussian"))+
coord_cartesian(ylim = c(0, 1))
ggplot(data = melt(data.frame(x,G,G2),id.vars = 'x'))+
geom_line(aes(x=x, y=value, color=variable),size=.5)+
scale_color_manual("Distribution",values=c("orange","blue"),labels=c("Gaussian","2Gaussian"))+
coord_cartesian(ylim = c(0, 1))
If it's not clear from these pictures that there is a problem, open up the images from these two links and flip from one to another.
http://rpubs.com/jwg/269311
http://rpubs.com/jwg/269312
NOTICE: The problem is even worse than I first described, since not only is the legend moving but the coordinate axis is moving as well.
Presumably this can be fixed by plotting both and then making its legend-item and the line invisible. Is this a possibility?
Here's a solution which will keep everything aligned with the bonus of animation.
library(ggplot2)
library(tidyr)
library(gganimate)
p <- df %>%
gather(var, val, -x) %>%
ggplot(aes(x, val, frame = var)) +
geom_line(aes(color = var, group = var, cumulative = TRUE)) +
coord_cartesian(ylim = c(0, 1))
gganimate(p, "myplot.gif", "gif")
This should generate a file myplot.gif with this result:
Not sure if this is what you want, but here goes:
x<-seq(-10,10,length=200)
G <- (1/(sqrt(2*pi))) * exp(-((x)^2)/(2))
G2 <- 2*(1/(pi))*(1/(x^2+1))
df <- data.frame(x,G,G2)
df.plot <- tidyr::gather(df, key = 'variable', value = 'value', -x)
ggplot(df.plot, aes(x, value, color = variable)) + geom_line() + scale_color_manual(breaks = c("G"), values = c("orange", NA)) +
coord_cartesian(xlim = c(-10, 10), ylim = c(0,1)) + theme(legend.position = c(0,0)) +
theme(legend.position = "right",
legend.justification = "top")
ggplot(df.plot, aes(x, value, color = variable)) + geom_line() + scale_color_manual(breaks = c("G", "G2"), values = c("orange", "blue")) +
coord_cartesian(xlim = c(-10, 10), ylim = c(0,1)) + theme(legend.position = "right",
legend.justification = "top")
I have a dataframe of multiple columns (let's say n) with different range and a vector of length n. I want different x-axis for each variable to be shown below each box plot. I tried facet_grid and facet_wrap but it gives common x axis.
This is what I have tried:
d <- data.frame(matrix(rnorm(10000), ncol = 20))
point_var <- rnorm(20)
plot.data <- gather(d, variable, value)
plot.data$test_data <- rep(point_var, each = nrow(d))
ggplot(plot.data, aes(x=variable, y=value)) +
geom_boxplot() +
geom_point(aes(x=factor(variable), y = test_data), color = "red") +
coord_flip() +
xlab("Variables") +
theme(legend.position="none")
If you can live with having the text of the x axis above the plot, and having the order of the graphs a bit messed-up this could work:
library(grid)
p = ggplot(plot.data, aes(x = 0, y=value)) +
geom_boxplot() +
geom_point(aes(x = 0, y = test_data), color = "red") +
facet_wrap(~variable, scales = "free_y", switch = "y") +
xlab("Variables") +
theme(legend.position="none") + theme_bw() + theme(axis.text.x=element_blank())
print(p, vp=viewport(angle=270, width = unit(.75, "npc"), height = unit(.75, "npc")))
I'm actually just creating the graph without flipping coords, so that scales = 'free_y' works, swithcing the position of the strip labels, and then rotating the graph.
If you don't like the text above graph (which is understandable), I would consider creating a list of single plots and then putting them together with grid.arrange.
HTH,
Lorenzo
How to add livery for the legend in geom_area? I tried something but it does not work.
time<-as.POSIXlt(c("2013-07-01","2013-07-01","2013-07-02","2013-07-02"),origin = "1960-01-01",tz="GMT")
data<-data.frame(xAxis=time,yAxis=c(3,2,1,2),split=factor(c(1,2,1,2)))
p<-ggplot(data,aes(x=xAxis,y=yAxis,fill=split))
p<-p + geom_area(stat="identity")
#p <- p + scale_color_discrete(name ="Name", labels=LETTERS[1:2])
p <- p + xlab("x-Axis") + ylab("y-Axis")
p
I think you need a scale that better matches your aes in ggplot
ggplot(data, aes(x = xAxis, y = yAxis, fill = split)) +
geom_area(stat = "identity") +
scale_fill_discrete(name = "Name", labels = LETTERS[1:2])
If you are going to use 'split' repeatedly and always want to have the same labels, you might consider re-labelling the factor before you start plotting (or whenever informative labels of a factor is relevant, e.g. modelling).
data$split2 <- factor(data$split, labels = LETTERS[1:2])
# no need for the 'labels' argument in scale
ggplot(data, aes(x = xAxis, y = yAxis, fill = split2)) +
geom_area(stat = "identity") +
scale_fill_discrete(name = "Name")