How to add legend to scatter plot in ggplot? - r

I have assigned a shape and color to each point, and I want to draw the legend according to the group data, but I can't add the legend..
library(datasets)
library(tidyverse)
library(reshape2)
name <- c("S1","S1","S1","S2","S2","S3","S3","S3","S4","S4","S5")
x <- c(1,5,9,8,5,6,7,4,3,6,4)
y <- c(3,8,9,5,7,5,3,8,9,3,4)
Shape <- c(21,21,21,22,22,23,23,23,24,24,25)
Color <- c("red","red","red","blue","blue","green","green","green","purple","purple","black")
df <- data.frame(x,y,name,Shape,Color)
graph1 <- ggplot(df,aes(x,y,fill = Color, shape = Shape))+
geom_point(size = 4)+
scale_shape_identity()+
scale_fill_identity()
graph1
the x and y is the main data. The name is the group. The Shape and Color is the shape and color I assigned for all those point. How to draw a legend according to the group?

I think you are looking for:
ggplot(df, aes(x = x ,y = y, fill = name, shape = name)) +
geom_point(size = 4) +
scale_fill_manual(values = unique(df$Color)) +
scale_shape_manual(values = unique(df$Shape))

You were missing aes parameter color :-)
library(datasets)
library(tidyverse)
library(reshape2)
name <- c('S1', 'S1', 'S1', 'S2', 'S2', 'S3', 'S3', 'S3', 'S4', 'S4', 'S5')
x <- c(1, 5, 9, 8, 5, 6, 7, 4, 3, 6, 4)
y <- c(3, 8, 9, 5, 7, 5, 3, 8, 9, 3, 4)
Shape <- c(21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 25)
Color <- c('red', 'red', 'red', 'blue', 'blue', 'green', 'green', 'green', 'purple', 'purple', 'black')
df <- data.frame(x, y, name, Shape, Color)
graph1 <- ggplot(df, aes(x, y, fill = Color, color = name, shape = Shape)) +
geom_point(size = 4) +
scale_shape_identity() +
scale_fill_identity()
graph1
You will note that using the group (name) as the basis for the legend makes this plot confusing, but in any case, you can add the color param to ensure that your legend is rendered.
if you use Color as the value for the color parameter you get the following:

Related

How to remove the default grey fill for linetype legend in barplot with ggplot2?

I have a bar-plot with two different variables.
For one of the factors (gr) I have chosen different ´lintype´ in the plot.
The legend for "gr" shows ´lintype´ but with a dark grey fill, which I think is confusing.
Does anyone know how to remove the fill or change it to white or transparent?
(All tips I have found only change a background to the legend, but does not affect the grey fill)
yval <- c(3, 7, 4, 4, 8, 9, 4, 7, 9, 6, 6, 3)
trt <- rep(c("A", "B", "C"), times=4)
gr <- rep(c(rep(("case"), times = 3), rep(("control"), times = 3)), times = 2)
var <- c(rep(("var1"), times = 6), rep(("var2"), times = 6))
df <- data.frame(yval, device, ccgroup, var)
ggplot(data=df, aes(x=var)) +
geom_bar( color = "black", size = 1, aes(weights = yval, fill = trt, linetype = gr) , position = "dodge")
This can be achieved e.g. via guide_legend which allows you to set the fill color used in the legend. Try this:
library(ggplot2)
yval <- c(3, 7, 4, 4, 8, 9, 4, 7, 9, 6, 6, 3)
trt <- rep(c("A", "B", "C"), times=4)
gr <- rep(c(rep(("case"), times = 3), rep(("control"), times = 3)), times = 2)
var <- c(rep(("var1"), times = 6), rep(("var2"), times = 6))
df <- data.frame(yval, trt, gr, var)
ggplot(data=df, aes(x=var)) +
geom_bar(color = "black", size = 1, aes(weights = yval, fill = trt, linetype = gr) , position = "dodge") +
guides(linetype = guide_legend(override.aes = list(fill = c(NA, NA))))
#> Warning: Ignoring unknown aesthetics: weights

My graphs legend is not showing the line graph part in ggplot (R)

I have created a graph using this code:
df.1 <- data.frame(
Month = c("Dec-17", "Jan-18", "Feb-18", "Mar-18", "Apr-18", "May-18"),
Total_1 = c(25, 14, 8, 16, 137, 170),
Total_2 = c(3, 2, 3, 2, 18, 27),
Total_3 = c(5, 4, 3, 2, 16, 54)
)
df.1 <- melt(df.1,id.vars = "Month")
#reorder the month column so it isn't alphabetical
df.1$Month <- factor(df.1$Month, levels(df.1$Month)[c(2,4,3,5,1,6)])
#partition my data into the 2 different graphs I need
df.1.1 <- df.1[7:18,]
df.1.2 <- df.1[1:6,]
ggplot(data = df.1.1, aes(x = Month, y = value)) +
geom_bar(aes(fill = variable), position = position_dodge(),stat = 'identity') +
geom_line(data = df.1.2, aes(x=Month, y=value, group=1), size =1.25, color = "#380B61") +
theme(axis.title.x=element_blank(), axis.title.y = element_blank(), legend.position="bottom", legend.direction="horizontal")
Which created this graph:
Example Graph
As you can see only the bar chart is showing on the legend. How can I get the line part (Total_1) to also show on the legend as well?
EDIT: To be clear I want the finished chart to look as close to this as possible:
Example Graph

Extra spaces between non latin characters in plots in R

When I use non-latin (Russian) characters in ggplot legend, the legend line becomes much longer. This example code shows the problem.
test <- data.frame(x = c(1, 2, 3, 4, 5, 6, 7, 8), y = c(1, 4, 9, 16, 25, 36, 25, 16), label = c('green / зеленый ', 'зеленый', 'red', 'white', 'yellow', 'pink', 'красный', 'синий' ))
ggplot(data = test, aes(x= x, y=y)) + geom_point(aes(colour = label), size = 20) + theme(legend.position = "bottom") +
guides(colour = guide_legend(nrow = 2))
Does anyone know the way to cure it? Thanks in advance.

Custom fill colour of bin with highest density in geom_histogram

My sample data frame goes as follows:
a <- structure(list(Middlepoint = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 1,
12, 13, 14, 15, 16, 17, 18, 19, 1, 1, 5, 5, 4, 4, 3, 7, 18, 8,
8, 8, 8, 8, 8.5, 8.5)), .Names = "Middlepoint", class = "data.frame", row.names = c(NA,
-34L))
I would like to create a histogram of binwidth = 1 and of the characteristics as follows:
library(ggplot2)
library(scales)
ggplot(a, aes(x = Middlepoint)) +
geom_histogram(aes(y = ..density.., fill=..density..), binwidth = 1) +
scale_x_continuous(breaks=0:19) +
scale_fill_continuous(low = "red", high = "green")
Now, what I cannot figure out is how to color just the bin of highest density (here, bin 8-9) with green color and all other bins with red (no gradient, just straight colors).
As you can see from the code above, the closest I could get to the desired outcome is to use scale_fill_continuous() component which is close but not exactly how I would like to see it.
I tried threads like ggplot change fill colour without losing colour gradient and R - ggplot2 histogram conditional fill color.
Any ideas how to generally custom fill histogram's bins?
You need to set the fill argument to a factor which takes 2 levels: one for all the density values lower then the max and one for the maximum density:
ggplot(a, aes(x = Middlepoint)) +
geom_histogram(aes(y = ..density..,
fill = cut(..density.., c(0, sort(..density.., TRUE)[1:2]))),
binwidth = 1) +
scale_fill_manual("", values = c("red", "green")) +
theme_minimal()

How to control ordering of stacked bar chart using identity on ggplot2

Using this dummy data.frame
ts <- data.frame(x=1:3, y=c("blue", "white", "white"), z=c("one", "one", "two"))
I try and plot with category "blue" on top.
ggplot(ts, aes(z, x, fill=factor(y, levels=c("blue","white" )))) + geom_bar(stat = "identity")
gives me "white" on top. and
ggplot(ts, aes(z, x, fill=factor(y, levels=c("white", "blue")))) + geom_bar(stat = "identity")
reverses the colors, but still gives me "white" on top. How can I get "blue" on top?
For what it is worth, in ggplot2 version 2.2.1 the order of the stack is no longer determined by the row order in the data.frame. Instead, it matches the order of the legend as determined by the order of levels in the factor.
d <- data.frame(
y=c(0.1, 0.2, 0.7),
cat = factor(c('No', 'Yes', 'NA'), levels = c('NA', 'Yes', 'No')))
# Original order
p1 <- ggplot(d, aes(x=1, y=y, fill=cat)) +
geom_bar(stat='identity')
# Change order of rows
p2 <- ggplot(d[c(2, 3, 1), ], aes(x=1, y=y, fill=cat)) +
geom_bar(stat='identity')
# Change order of levels
d$cat2 <- relevel(d$cat, 'Yes')
p3 <- ggplot(d, aes(x=1, y=y, fill=cat2)) +
geom_bar(stat='identity')
grid.arrange(p1, p2, p3, ncol=3)
It results in the below plot:
I've struggled with the same issue before. It appears that ggplot stacks the bars based on their appearance in the dataframe. So the solution to your problem is to sort your data by the fill factor in the reverse order you want it to appear in the legend: bottom item on top of the dataframe, and top item on bottom:
ggplot(ts[order(ts$y, decreasing = T),],
aes(z, x, fill=factor(y, levels=c("blue","white" )))) +
geom_bar(stat = "identity")
Edit: More illustration
Using sample data, I created three plots with different orderings of the dataframe, I thought that more fill-variables would make things a bit clearer.
set.seed(123)
library(gridExtra)
df <- data.frame(x=rep(c(1,2),each=5),
fill_var=rep(LETTERS[1:5], 2),
y=1)
#original order
p1 <- ggplot(df, aes(x=x,y=y,fill=fill_var))+
geom_bar(stat="identity") + labs(title="Original dataframe")
#random order
p2 <- ggplot(df[sample(1:10),],aes(x=x,y=y,fill=fill_var))+
geom_bar(stat="identity") + labs(title="Random order")
#legend checks out, sequence wird
#reverse order
p3 <- ggplot(df[order(df$fill_var,decreasing=T),],
aes(x=x,y=y,fill=fill_var))+
geom_bar(stat="identity") + labs(title="Reverse sort by fill")
plots <- list(p1,p2,p3)
do.call(grid.arrange,plots)
Use the group aethetic in the ggplot() call. This ensures that all layers are stacked in the same way.
series <- data.frame(
time = c(rep(1, 4),rep(2, 4), rep(3, 4), rep(4, 4)),
type = rep(c('a', 'b', 'c', 'd'), 4),
value = rpois(16, 10)
)
ggplot(series, aes(time, value, group = type)) +
geom_col(aes(fill = type)) +
geom_text(aes(label = type), position = "stack")
Messing with your data in order to make a graph look nice seems like a bad idea. Here's an alternative that works for me when using position_fill():
ggplot(data, aes(x, fill = fill)) + geom_bar(position = position_fill(reverse = TRUE))
The reverse = TRUE argument flips the order of the stacked bars. This works in position_stack also.
I have the exactly same problem today. You can get blue on top by using order=-as.numeric():
ggplot(ts,
aes(z, x, fill=factor(y, levels=c("blue","white")), order=-as.numeric(y))) +
geom_bar(stat = "identity")
I had a similar issue and got around by changing the level of the factor. thought I'd share the code:
library(reshape2)
library(ggplot2)
group <- c(
"1",
"2-4",
"5-9",
"10-14",
"15-19",
"20-24",
"25-29",
"30-34",
"35-39",
"40-44",
"45-49"
)
xx <- factor(group, levels(factor(group))[c(1, 4, 11, 2, 3, 5:10)])
method.1 <- c(36, 14, 8, 8, 18, 1, 46, 30, 62, 34, 34)
method.2 <- c(21, 37, 45, 42, 68, 41, 16, 81, 51, 62, 14)
method.3 <- c(37, 46, 18, 9, 16, 79, 46, 45, 70, 42, 28)
elisa.neg <- c(12, 17, 18, 6, 19, 14, 13, 13, 7, 4, 1)
elisa.eq <- c(3, 6, 3, 14, 1, 4, 11, 13, 5, 3, 2)
test <- data.frame(person = xx,
"Mixture Model" = method.1,
"Censoring" = method.3,
"ELISA neg" = elisa.neg,
"ELISA eqiv" = elisa.eq)
melted <- melt(test, "person")
melted$cat <- ifelse(melted$variable == "Mixture.Model", "1",
ifelse(melted$variable == "Censoring", "2", "3"))
melted$variable = factor(melted$variable, levels = levels(melted$variable)[c(1, 2, 4,3 )]) ## This did the trick of changing the order
ggplot(melted, aes(x = cat, y = value, fill = variable)) +
geom_bar(stat = 'identity') + facet_wrap(~ person) +
theme(axis.ticks.x=element_blank(),
axis.text.x=element_blank()) +
labs(title = "My Title",
y = "Per cent", x = "Age Group", fill = "")
(Sorry, this is my data, I didn't reproduce using the data from the original post, hope it's ok!)

Resources