I am trying to create a line plot with 2 types of measurements, but my data is missing some x values. In Line break when no data in ggplot2 I have found how to create plot that will make a break when there is now data, but id does not allow to plot 2 lines (one for each Type).
1) When I try
ggplot(Data, aes(x = x, y = y, group = grp)) + geom_line()
it makes only one line, but with break when there is no data
2) When I try
ggplot(Data, aes(x = x, y = y, col = Type)) +
geom_line()
it makes 2 lines, but with break when there is no data
3) When I try
ggplot(Data, aes(x = x, y = y, col = Type, group = grp)) +
geom_line()
it makes unreadyble chart
4) of course I could combine the Type and grp to make new variable, but then the legend is not nice, and I get 4 groups (and colours) insted of 2.
5) also I could make something like that, but it dose not produce a legend, and in my real dataset i have way to many Types to do that
ggplot() +
geom_line(data = Data[Data$Type == "A",], aes(x = x, y = y, group = grp), col = "red") +
geom_line(data = Data[Data$Type == "B",], aes(x = x, y = y, group = grp), col = "blue")
Data sample:
Data <- data.frame(x = c(1:100, 201:300), y = rep(c(1, 2), 100), Type = rep(c("A", "B"), 100), grp = rep(c(1, 2), each = 100))
One way is to use interaction() to specify a grouping of multiple columns:
library(ggplot2)
Data <- data.frame(x = c(1:100, 201:300), y = rep(c(1, 2), 100), Type = rep(c("A", "B"), 100), grp = rep(c(1, 2), each = 100))
ggplot(Data, aes(x = x, y = y, col = Type, group = interaction(grp,Type))) +
geom_line()
Related
I have this data frame
df <- data.frame(profile = rep(c(1,2), times = 1, each = 3), depth = c(100, 200, 300), value = 1:3)
This is my plot
ggplot() +
geom_bar(data = df, aes(x = profile, y = - depth, fill = value), stat = "identity")
My problem is the y labels which doesn't correspond to the depth values of the data frame
To help, my desired plot seems like this :
ggplot() +
geom_point(data = df, aes(x = profile, y = depth, colour = value), size = 20) +
xlim(c(0,3))
But with bar intead of points vertically aligned
nb : I don't want to correct it manually in changing ticks with scale_y_discrete(labels = (desired_labels))
Thanks for help
Considering you want a y-axis from 0 to -300, using facet_grid() seems to be a right option without summarising the data together.
ggplot() + geom_bar(data = df, aes(x = as.factor(profile), y = -depth, fill = value), stat = 'identity') + facet_grid(~ value)
I have it !
Thanks for your replies and to this post R, subtract value from previous row, group by
To resume; the data :
df <- data.frame(profile = rep(c(1,2), times = 1, each = 3), depth = c(100, 200, 300), value = 1:3)
Then we compute the depth step of each profile :
df$diff <- ave(df$depth, df$profile, FUN=function(z) c(z[1], diff(z)))
And finally the plot :
ggplot(df, aes(x = factor(profile), y = -diff, fill = value)) + geom_col()
Here is my data
set.seed(42)
dat = data.frame(iter = rep(1:3, each = 10),
variable = rep(rep(letters[1:2], each = 5), 3),
value = rnorm(30))
I know I can draw violin plots for a and b with
library(ggplot2)
ggplot(data = dat, aes (x = variable, y = value)) + geom_violin()
But how do I draw violin plots for each iteration of a and b so that there will be three plots for a next to three plots for b. I have done it previously using base plot but I am looking for a better solution since the number of iterations as well as number of 'a's and 'b's keeps on changing.
There are two possible ways. One would be by adding a fill command, the other using facet_wrap (or facet_grid)
With fill:
ggplot(data = dat, aes (x = variable, y = value, fill = as.factor(iter))) + geom_violin(position = "dodge")
Or using facet_wrap:
ggplot(data = dat, aes (x = as.factor(iter), y = value)) + geom_violin(position = "dodge") + facet_wrap(~variable)
Maybe there is a better way but in this kind of situation I usually create a new variable:
set.seed(42)
dat = data.frame(iter = rep(1:3, each = 10),
variable = rep(rep(letters[1:2], each = 5), 3),
value = rnorm(30))
dat <- dat %>% mutate(x_axis = as.factor(as.numeric(factor(variable))*100 + 10*iter))
levels(dat$x_axis)<- c("a1", "a", "a3", "b2", "b", "b3")
ggplot(data = dat,
aes(x = x_axis,
y = value, fill =variable)) + geom_violin() + scale_x_discrete(breaks = c("a","b"))
Result is:
I have a ggplot graph defined like this:
x <- seq(0, 10, by = 0.1)
y1 <- cos(x)
y2 <- sin(x)
df1 <- data.frame(x = x, y = y1, type = "sin", id = 1)
df2 <- data.frame(x = x, y = y2, type = "cos", id = 2)
df3 <- data.frame(x = 2, y = 0.5, type = "constant", id = 3)
df4 <- data.frame(x = 4, y = 0.2, type = "constant", id = 4)
combined <- rbind(df1, df2, df3, df4)
ggplot(combined, aes(x, y, colour = interaction(type, id))) + geom_line() +
geom_point(data = subset(combined, type == "constant"))
This works very well as illustrated below:
Now I would like to extract the interaction in a variable to reuse it later (e.g. customize the legend style or labels).
I did that in a very naïve way:
my.interaction <- interaction(combined$type, combined$id)
ggplot(combined, aes(x, y, colour = my.interaction)) + geom_line() +
geom_point(data = subset(combined, type == "constant"))
But then I have an error:
Error: Aesthetics must be either length 1 or the same as the data (2):
x, y, colour
Edit:
Here is the kind of manipulation I could do: edit the linetype of the legend
displayed <- levels(factor(my.interaction))
line.style <- rep(1, length.out = length(displayed))
line.style[grep("constant", displayed)] <- 0
That works:
ggplot(combined, aes(x, y, colour = interaction(type, id))) + geom_line() +
geom_point(data = subset(combined, type == "constant")) +
guides(colour=guide_legend(override.aes=list(linetype = line.style)))
That does not:
ggplot(combined, aes(x, y, colour = my.interation) + geom_line() +
geom_point(data = subset(combined, type == "constant")) +
guides(colour=guide_legend(override.aes=list(linetype = line.style)))
In the end, I could also edit the shapes or the legend labels (e.g. "Id: 1 / Type: sin" or any other advanced transformation of the labels based on the interaction values).
This'll work. What's wrong with adding a column to your data frame?
combined %>% mutate(my.interaction = paste(type, id, sep='.')) %>%
ggplot(aes(x, y, colour = my.interaction)) + geom_line() +
geom_point(data = subset(combined, type == "constant"))
If you look at this
ggplot(mtcars,aes(x=disp,y=mpg,colour=mpg))+geom_line()
you will see that the line colour varies according to the corresponding y value, which is what I want, but only section-by-section. I would like the colour to vary continuously according to the y value. Any easy way?
One possibility which comes to mind would be to use interpolation to create more x- and y-values, and thereby make the colours more continuous. I use approx to " linearly interpolate given data points". Here's an example on a simpler data set:
# original data and corresponding plot
df <- data.frame(x = 1:3, y = c(3, 1, 4))
library(ggplot2)
ggplot(data = df, aes(x = x, y = y, colour = y)) +
geom_line(size = 3)
# interpolation to make 'more values' and a smoother colour gradient
vals <- approx(x = df$x, y = df$y)
df2 <- data.frame(x = vals$x, y = vals$y)
ggplot(data = df2, aes(x = x, y = y, colour = y)) +
geom_line(size = 3)
If you wish the gradient to be even smoother, you may use the n argument in approx to adjust the number of points to be created ("interpolation takes place at n equally spaced points spanning the interval [min(x), max(x)]"). With a larger number of values, perhaps geom_point gives a smoother appearance:
vals <- approx(x = df$x, y = df$y, n = 500)
df2 <- data.frame(x = vals$x, y = vals$y)
ggplot(data = df2, aes(x = x, y = y, colour = y)) +
geom_point(size = 3)
Since ggplot2 v0.8.5 one can use geom_line or geom_path with different lineend options (right now there are three options: round, butt and square). Selection depends on the nature of the data.
round would work on sharp edges (like in given OPs data):
library(ggplot2)
ggplot(mtcars, aes(disp, mpg, color = mpg)) +
geom_line(size = 3, lineend = "round")
square would work on a more continuous variable:
df <- data.frame(x = seq(0, 100, 10), y = seq(0, 100, 10) ^ 2)
ggplot(data = df, aes(x = x, y = y, colour = y)) +
geom_path(size = 3, lineend = "square")
Maybe this will work for you:
library(dplyr)
library(ggplot2)
my_mtcars <-
mtcars %>%
mutate(my_colors = cut(disp, breaks = c(0, 130, 200, 400, Inf)))
ggplot(my_mtcars, aes(x = disp, y = mpg, col = mpg)) +
geom_line() + facet_wrap(~ my_colors, scales = 'free_x')
Here is the code for the plot
library(ggplot2)
df <- data.frame(gp = factor(rep(letters[1:3], each = 10)), y = rnorm(30))
library(plyr)
ds <- ddply(df, .(gp), summarise, mean = mean(y), sd = sd(y))
ggplot(df, aes(x = gp, y = y)) +
geom_point() +
geom_point(data = ds, aes(y = mean), colour = 'red', size = 3)
I want to have a legend for this plot that will identify the data values and mean values some thing like this
Black point = Data
Red point = Mean.
How can I achieve this?
Use a manual scale, i.e. in your case scale_colour_manual. Then map the colours to values in the scale using the aes() function of each geom:
ggplot(df, aes(x = gp, y = y)) +
geom_point(aes(colour="data")) +
geom_point(data = ds, aes(y = mean, colour = "mean"), size = 3) +
scale_colour_manual("Legend", values=c("mean"="red", "data"="black"))
You can combine the mean variable and data in the same data.frame and colour /size by column which is a factor, either data or mean
library(reshape2)
# in long format
dsl <- melt(ds, value.name = 'y')
# add variable column to df data.frame
df[['variable']] <- 'data'
# combine
all_data <- rbind(df,dsl)
# drop sd rows
data_w_mean <- subset(all_data,variable != 'sd',drop = T)
# create vectors for use with scale_..._manual
colour_scales <- setNames(c('black','red'),c('data','mean'))
size_scales <- setNames(c(1,3),c('data','mean') )
ggplot(data_w_mean, aes(x = gp, y = y)) +
geom_point(aes(colour = variable, size = variable)) +
scale_colour_manual(name = 'Type', values = colour_scales) +
scale_size_manual(name = 'Type', values = size_scales)
Or you could not combine, but include the column in both data sets
dsl_mean <- subset(dsl,variable != 'sd',drop = T)
ggplot(df, aes(x = gp, y = y, colour = variable, size = variable)) +
geom_point() +
geom_point(data = dsl_mean) +
scale_colour_manual(name = 'Type', values = colour_scales) +
scale_size_manual(name = 'Type', values = size_scales)
Which gives the same results