I have a plot with pairs of points that are slightly offset. Each pair of points has associated error bars. I have specified that the symbol of the first point in the pair is different from that of the second (closed circle vs open circle). I would like it so that the error bars do not show through the open symbol.
Here is a mock data set:
x = runif(4,-2,2)
x_1 = runif(4,-1,3)
dfr <- data.frame(
x = c(x, x_1),
y = rep(c("A","B","C","D"), 2),
upper = c(x+2, x_1+1),
lower = c(x-2, x_1-2),
type = rep(c("alpha", "beta"), each = 4))
And here is the plot:
dodge=position_dodge(width=0.5)
ggplot(dfr,aes(x=y,y=x,colour=type)) +
geom_point(size=8,aes(shape=type),position=dodge) +
geom_errorbar(aes(ymax=upper,ymin=lower),position = dodge) +
scale_colour_manual(values = c('gray','black')) +
scale_shape_manual(values = c(19,21)) +
coord_flip() +
opts(legend.position="none")
Thanks for any help you can provide!
I can't think of a way to make an 'open' point and not let the errorbar show trough. The only way of doing this would be to fill the points with the same colour as the background, but then your gridlines won't be visible through the point.
To do this, map the fill aesthetic to type, and specify scale_fill_manual with the fill colour grey90 which is the theme_grey setting:
ggplot(dfr,aes(x=y,y=x,colour=type, fill=type)) +
geom_errorbar(aes(ymax=upper,ymin=lower),position = dodge) +
geom_point(size=8,aes(shape=type),position=dodge) +
scale_colour_manual(values = c('gray','black')) +
scale_fill_manual(values=c('grey', 'grey90')) +
scale_shape_manual(values = c(19,21)) +
coord_flip() +
opts(legend.position="none")
Why don't you just use color as shown in the modified code below. It will fill the black circles too. Not sure if that is acceptable.
ggplot(dfr,aes(x=y,y=x,colour=type)) +
geom_point(size=8,position=dodge) +
geom_errorbar(aes(ymax=upper,ymin=lower),position = dodge) +
scale_colour_manual(values = c('gray','black')) +
coord_flip() +
opts(legend.position="none")
Related
I'm trying to use ggplot2 to make some sort of timeline using values from a dataframe (df). I've managed to plot the data exactly how I want it (the different colored line segments connecting the x-marks in this exact order, i.e., from left to right: 'early', 'unknown', 'late', 'sub'). The startpoint and endpoint columns in the dataframe are used to define the positions of the points and line segments.
The problem is that the legend doesn't show the color of the 'x' icons, they are just grey. I've tried adding scale_color_manual() and scale_fill_manual() commands but they don't seem to change anything. The legend does display the correct color when I change the shape to shape = 21, however, I really want the shape to be 4 (x icons). I don't care about the shape of the legend though but scale_shape_manual() again didn't change anything about the legend.
I have also tried placing different color arguments inside and outside the aes() argument of ggplot(), geom_segment() and/or geom_point().
How can I make the icons from the legend show the correct color?
Below I added a piece of code to reproduce the problem.
library(ggplot2)
library(RColorBrewer)
## Define dataframe
df <- data.frame(Var = c("sub","late","unknown","early"),
Time = c(10,267,0,1256),
Endpoint = c(1533,1523,1256,1256),
Startpoint = c(1523,1256,1256,0))
colorscheme <- RColorBrewer::brewer.pal(9, "Set1")[c(1,4,2,3)]
## Make plot
ggplot(df, aes(x="", y=Endpoint, fill=Var), color =colorscheme) +
geom_segment( aes(x="", xend="", y=Startpoint, yend=Endpoint), color = colorscheme) +
geom_point(aes(x="", y=Endpoint),size=5, shape=4 , color = colorscheme) +
coord_flip()
Thanks in advance for any suggestions!
You should use color instead of fill. To remove the line from the legend, use guides(color = guide_legend(override.aes = list(linetype = 0))) or use show.legend = F in geom_segment.
Also, arguments passed in ggplot need not to be repeated afterward.
ggplot(df, aes(x="", y=Endpoint, color=Var), colorscheme) +
geom_segment(aes(xend="", y=Startpoint, yend=Endpoint)) +
geom_point(size=5, shape=4) +
coord_flip() +
guides(color = guide_legend(override.aes = list(linetype = 0)))
#or
ggplot(df, aes(x="", y=Endpoint, color=Var), colorscheme) +
geom_segment(aes(xend="", y=Startpoint, yend=Endpoint)) +
geom_point(size=5, shape=4) +
coord_flip()
Try this:
ggplot(df, aes(x = "", y = Endpoint, color = Var), colorscheme) +
geom_segment(aes(x = "", xend = "", y = Startpoint, yend = Endpoint), show.legend = FALSE) +
geom_point(aes(x = "", y = Endpoint), size = 5, shape = 4) +
coord_flip()
In this way legend will show only X
I've made a histogram graph that shows the distribution of lidar returns per elevation for three lidar scans I have done.
I've converted my data to long format, with:
one column called 'value', describing the z position of each point
one column called 'variable', containing the name of each
scan group
In the attached image you can see the histograms of my three scan groups. I am currently using viridis to color the histogram by scan group (ie. the name of the scan in the variable column). However, I want to match the colours in the graph with colours I already have.
How might I do this?
The hexcols I'd like to like color each of my three histograms with are:
lightgreen = "#62FE96"
lightred = "#FE206B"
darkpurple = "#62278E"
A link to my data - 'density2'
My current code:
library(tidyverse)
library(viridisLite)
library(viridis)
# histogram
p <- density2 %>%
ggplot( aes(x=value,color = variable, show.legend = FALSE)) +
geom_histogram(binwidth = 1, alpha = 0.5, position="identity") +
scale_color_viridis(discrete =TRUE) +
scale_fill_viridis(discrete=TRUE) +
theme_bw() +
labs(fill="") +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())
p + scale_y_sqrt() + theme(legend.position="none") + labs(y = "data pts", x = "elevation (m)")
Any help would be most appreciated!
Delete the scale_color_viridis and scale_fill_viridis lines - these are applying the Viridis color scale. Replace with scale_fill_manual(values = c(lightgreen, lightred, darkpurple)). And in your aesthetic mapping replace color = variable with fill = variable. For a histogram, color refers to the color of the lines outlining each bar, and fill refers to the color each bar is filled in.
This should leave you with:
p <- density2 %>%
ggplot(aes(x = value, fill = variable)) +
geom_histogram(binwidth = 1, alpha = 0.5, position = "identity") +
scale_fill_manual(values = c(lightgreen, lightred, darkpurple)) +
theme_bw() +
labs(fill = "") +
theme(panel.grid = element_blank())
p + scale_y_sqrt() +
theme(legend.position = "none") +
labs(y = "data pts", x = "elevation (m)")
I've also done some other clean-up. show.legend = FALSE does not belong inside aes() - and your theme(legend.position = "none") should take care of it.
I did not download your data, save it in my working directory, import it into R, and test this code on it. If you need more help, please post a small subset of your data in a copy/pasteable format (e.g., dput(density2[1:20, ]) for the first 20 rows---choose a suitable subset) and I'll be happy to test and adjust.
I'm trying to add shapes on the lines plotted using geom_freqpoly to give more visibility to them if the plot is printed b/w on paper.
data <- data.frame(time=runif(1000,0,20000),
class=c("a","b","c","d"))
ggplot(data, aes(time, colour = class)) + geom_freqpoly(binwidth = 1000) + geom_point(aes(shape=class))
but this generates this error:
'Error: geom_point requires the following missing aesthetics: y'
How can I solve this error?
Another thing is that I want to use a single colour (eg. blue) to draw the lines
but with scale_colour_brewer() I can't change the colour scale, I want to change it because the lightest colour is nearly white and you can barely see it.
How can I add a custom min and max for the colours?
How about this? The error you are getting is being produced by geom_point which needs x and y, so I removed it.
ggplot(data, aes(x = time, color = class)) +
geom_freqpoly(binwidth = 1000) +
scale_color_brewer(palette = "Blues") +
theme_dark()
If you don't want the dark background, pass manual values from RColorBrewer. The following example uses every second color to increase the contrast.
p1 <- ggplot(data, aes(x = time, color = class)) +
geom_freqpoly(binwidth = 1000) +
scale_color_manual(values = RColorBrewer::brewer.pal(9, name = "Blues")[c(3, 5, 7, 9)])
EDIT
You can extract summarised data from a ggplot object using layer_data function.
xy <- layer_data(p1)
ggplot(xy, aes(x = x, y = count, color = colour)) +
theme_bw() +
geom_line() +
geom_point() +
scale_color_manual(values = RColorBrewer::brewer.pal(9, name = "Blues")[c(3, 5, 7, 9)])
I have data that looks like this
df = data.frame(x=sample(1:5,100,replace=TRUE),y=rnorm(100),assay=sample(c('a','b'),100,replace=TRUE),project=rep(c('primary','secondary'),50))
and am producing a plot using this code
ggplot(df,aes(project,x)) + geom_violin(aes(fill=assay)) + geom_jitter(aes(shape=assay,colour=y),height=.5) + coord_flip()
which gives me this
This is 90% of the way to being what I want. But I would like it if each point was only plotted on top of the violin plot for the matching assay type. That is, the jitterred positions of the points were set such that the triangles were only ever on the upper teal violin plot and the circles in the bottom red violin plot for each project type.
Any ideas how to do this?
In order to get the desired result, it is probably best to use position_jitterdodge as this gives you the best control over the way the points are 'jittered':
ggplot(df, aes(x = project, y = x, fill = assay, shape = assay, color = y)) +
geom_violin() +
geom_jitter(position = position_jitterdodge(dodge.width = 0.9,
jitter.width = 0.5,
jitter.height = 0.2),
size = 2) +
coord_flip()
which gives:
You can use interaction between assay & project:
p <- ggplot(df,aes(x = interaction(assay, project), y=x)) +
geom_violin(aes(fill=assay)) +
geom_jitter(aes(shape=assay, colour=y), height=.5, cex=4)
p + coord_flip()
The labeling can be adjusted by numeric scaled x axis:
# cbind the interaction as a numeric
df$group <- as.numeric(interaction(df$assay, df$project))
# plot
p <- ggplot(df,aes(x=group, y=x, group=cut_interval(group, n = 4))) +
geom_violin(aes(fill=assay)) +
geom_jitter(aes(shape=assay, colour=y), height=.5, cex=4)
p + coord_flip() + scale_x_continuous(breaks = c(1.5, 3.5), labels = levels(df$project))
I have a plot made with GGplot2. Now when i want to change the size of my text points within the plot, the size of the text does not change. I use the following line of code:
ggplot(data = out, aes(x = V2, y = V1)) +
****geom_text(data = out[!is.na(out$V1),], aes(label = labels, alpha=0.3, size=0.1))**** +
facet_grid(id1 ~ id2,scales="fixed")+
geom_text(data=df.text,aes(pos,pos,label=id1)) + geom_abline( slope=1 ) +
ggtitle("Corralation between measured & calculated affinities") +
ylab("") + xlab("") + theme(panel.grid.minor.x=element_blank(), panel.grid.major.x=element_blank())
}
I put ** between start and end of the line of interest fat. I know that size is the right parameter to change, but why isn't my text changing when for instance making size=0.01.
Thanks to Adam Kimberley, the size parameter should be moved outside of the 2nd brackets like this geom_text(data = out[!is.na(out$V1),], aes(label = labels), size=0.1, alpha=0.3)
Than size of the text alters.