I want to produce a barplot overlayed with dots where both have separate legends. Also, I want to choose the color of the bars and the size of the dots using the arguments outside aes(). As both are not mapped, no legend is produced.
1) How can I add a legend manually for both fill and size?
library(ggplot2)
d <- data.frame(group = 1:3,
prop = 1:3 )
ggplot(d, aes(x=group, y=prop)) +
geom_bar(stat="identity", fill="red") +
geom_point(size=5)
This is what I came up with: I used dummy mappings and modified the legend according to my needs afterwards. But this approach appears clumsy to me.
2) Is there a manual way to say: Add a legend with this title, these shapes, these colors etc.?
d <- data.frame(dummy1="d1",
dummy2="d2",
group = 1:3,
prop = 1:3 )
ggplot(d, aes(x=group, y=prop, fill=dummy1, size=dummy2)) +
geom_bar(stat="identity", fill="red") +
geom_point(size=5) +
scale_fill_discrete(name="fill legend", label="fill label") +
scale_size_discrete(name="size legend", label="size label")
Above I mapped fill to dummy1. So I would expect scale_fill_discrete to alter this legend. But it appears to modify the size legend instead.
3) I am not sure what went wrong here. Any ideas?
I'm not sure why you say "Also, I want to choose the color of the bars and the size of the dots using the arguments outside aes()". Is it something you're trying to do or is it something that you have to do given how ggplot works?
If it's the latter, one solution is as under -
library(ggplot2)
d <- data.frame(group = 1:3,
prop = 1:3 )
ggplot(d, aes(x=group, y=prop)) +
geom_bar(stat="identity",aes( fill="label")) +
geom_point(aes(size='labelsize')) +
scale_fill_manual(breaks = 'label', values = 'red')+
scale_size_manual(breaks = 'labelsize', values = 5)
Related
how can be colored the dots next to the legend labels? scale_color_manual or scale_fill_manual do not work. Also how can I change the dots in the legend to squares? Thanks
set.seed(1)
library(ggplot2)
library(ggrepel)
df <- data.frame(n=runif(8),y=1:8,l=letters[1:8],col=palette.colors(8))
p_vol <- ggplot(df, aes(n, y, label = l)) +
geom_point(aes(fill=l),color = df$col) +
geom_text_repel(col=df$col)+theme_classic()
print(p_vol)
You're going to need to include the color argument within the aesthetic call in geom_point(), setting color = l. Then you can use scale_color_manual to use the desired colors.
p_vol <- ggplot(df, aes(n, y, label = l)) +
geom_point(aes(fill=l, color = l)) +
geom_text_repel(col=df$col) +
theme_classic() +
scale_color_manual(values = df$col)
Also you can try enabling fill from aes() using the colors you have in your dataframe. Here the code, I have used different colors because I do not have enough knowledge about the function palette.colors you used to have the colors. Also using scale_fill_identity() takes the colors directly from the variable in your data (Those defined in fill). Here the code:
set.seed(1)
library(ggplot2)
library(ggrepel)
library(RColorBrewer)
df <- data.frame(n=runif(8),y=1:8,l=letters[1:8],col=rainbow(8))
#Plot
ggplot(df, aes(n, y, label = l,color=l,fill=col)) +
geom_point() +
geom_text_repel(show.legend = F)+theme_classic()+
scale_fill_identity()
Output:
Given a ggplot plot generated using the following code
size = 10000
d = data.frame(
type = rep(c("A","B","C"), each=size),
val = c(rnorm(size, 0, 1), rnorm(size, 1, 2),rnorm(size, 2, 3))
)
require(ggplot2)
(
ggplot(subset(d, is.element(type, c("A", "C"))), aes(x=val))
+ geom_histogram(aes(y=..density..), bins=100, position="identity", alpha=0.5)
+ geom_line(aes(color=type), stat="density", size=1)
)
Is it possible to add a grey square with a custom label representing the simple histogram to the legend? Can it be done without creating a dummy item?
All you need is to put fill= into aes() for the geom_histogram() line. You don't have a column in your dataset to assign to this, but if you assign fill="string name" in aes(), then ggplot will create a fill legend with that as the label.
Of course, the color will default to the ggplot "red" color, so if you want to go with gray again, you have to set that with scale_fill_manual(), since fill= outside aes() will overwrite anything you put within aes().
ggplot(d, aes(x=val)) +
geom_histogram(aes(y=..density.., fill='histogram'),
bins=100, position="identity", alpha=0.5) +
geom_line(aes(color=type), stat="density", size=1) +
scale_fill_manual(values='gray20')
I need to create one-row heatmap, that occasionally will be derived from NA-only column, but has to be displayed anyway. In the example below generating heatmap from p2 column will render "Error: Must request at least one colour from a hue palette.". Is there any way to force ggplot to display an "empty" heatmap?
library(ggplot2)
id <- letters[1:5]
p1 <- factor(c(1,NA,2,NA,3))
p2 <- factor(c(NA,NA,NA,NA,NA))
dat <- data.frame(id=id, p1=p1, p2=p2)
ggplot(dat, aes(x=id,y="identity")) + geom_tile(aes(fill = p1), colour = "white") #works fine
ggplot(dat, aes(x=id,y="identity")) + geom_tile(aes(fill = p2), colour = "white") #renders error
I think if you explicitly tell ggplot how to handle NA values using the na.value inside a scale_fill_manual call. This should take care of your issue, or at least head you in the right direction:
ggplot(dat, aes(x=id,y="identity")) +
geom_tile(aes(fill = p2), colour = "white") +
scale_fill_manual(values = "white",
na.value = "black")
You can change the values argument to better handle the colors you like
I have the following plot but do not want the legend for point size to show. Also how can I change the title for the factor(grp)? Sorry I know this should be an easy one but I am stuck.
df1<-data.frame(x=c(3,4,5),y=c(15,20,25),grp=c(1,2,2))
p<-ggplot(df1,aes(x,y))
p<-p+ geom_point(aes(colour=factor(grp),size=4))
p
df2<-data.frame(x=c(3.5,4.5,5.5),y=c(15.5,20.5,25.5))
p<-p + geom_path(data=df2,aes(x=x,y=y))
p
To change the legend title, it's easier (I find) to just change the data frame title:
df1$grp = factor(df1$grp)
colnames(df1)[3] = "Group"
The reason why size appears in the legend, is because you have made it an aesthetic - it's not! An aesthetic is something that varies with data. Here size is fixed:
p = ggplot(df1,aes(x,y))
p = p+ geom_point(aes(colour=Group), size=4)
You can also change the name of the legend in ggplot itself:
p = p + scale_colour_discrete(name="Group")
Leave the size out of the aesthetics.
ggplot(df1,aes(x,y)) + geom_point(aes(colour = factor(grp)), size=4) +
scale_colour_discrete(name = "Grp")
I am developing a graph in R with ggplot2 that has two geoms (one geom_line and one geom_text). It draws a line graph and then places text labels on start and end points of each line segment.
(myplot <- ggplot(data=datatable, aes(x, y, group = group,colour = group, label=mylabels)) + geom_line(size = 1.5))
myplot + geom_text(color = "black")
Now my question is how can I do the following tasks in ggplot2, they all work when I only have one geom but not with both (seems that they overide each other)
1 - making the background white.
The following code works with geom_line but as soon as I add geom_text it becomes gray again. Even if I add this line after geom_text it gets rid of the point labels that are on the chart.
myplot + opts(panel.background = theme_rect(fill = "white", colour = NA))
2- x labels and x label format. Again the following code works with only one geom but breaks when I have the second geom
myplot + scale_x_date(format="%m", 'my x label')
3- While we are on it how can I put the legend at the bottom and spread it horizontally (p + opts(legend.position="bottom")) spreads that vertically that looks very stupid.
For 1), you haven't saved the object myplot after the second and third calls involving it. This works for me:
set.seed(3)
dat <- data.frame(x = runif(10), y = rnorm(10), group = gl(2,5),
mylabel = paste(1:10, "foo"))
require(ggplot2)
myplot <- ggplot(data=dat, aes(x, y, group = group, colour = group,
label = mylabel)) + geom_line(size = 1.5)
myplot + geom_text(color = "black") +
opts(panel.background = theme_rect(fill = "white", colour = NA))
Note that I only ever save myplot once. The second call involving myplot modifies it on the fly but doesn't save it.
For the rest, you'll need to provide a reproducible example.