Custom fill colour of bin with highest density in geom_histogram - r

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()

Related

How to add legend to scatter plot in ggplot?

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:

Change panel width ggplot2

I am creating some plots with ggplot2 and I would like to add stats to it post-hoc. However, I have the issue that the plot ends so close to the margin that I don't have space to add it. Here is a picture:
I would like to draw the stars etc at the right hand side of each plot. So I would like to just have some extra space at the right hand side of each panel. I have been trying to find a command for that but it hasn't been going well...
Here is the code I'm using to plot:
df %>%
group_by(group, animal, day, zone) %>%
summarise(sum_cum = sum(cum_time_sec)) %>%
ggline(x='day', y='sum_cum', color = 'group', fill = ' group', size = 1.1, outlier.shape = NA,
add = c("mean_se"), add.params = list(alpha=0.5), point.size = 4, linetype = 1, facet.by = "zone", ncol = 4)
Thank you!
Without data, it's always more difficult to show a working solution, but we can replicate your plot approximately by doing:
library(ggpubr)
library(dplyr)
df <- data.frame(group = rep(c('A', 'B'), each = 20),
animal = 1, day = rep(1:5, 8), zone = rep(rep(1:4, each = 5), 2),
cum_time_sec = c(5, 10, 11, 10, 8, 10, 9, 8, 7, 8, 40, 35, 37,
39, 41, 5, 4, 3, 4, 5, 4, 4, 4, 5, 3, 10, 6, 7,
8, 6, 40, 45, 44, 45, 49, 4, 3, 4, 2, 1))
p <- df %>%
group_by(group, animal, day, zone) %>%
summarise(sum_cum = sum(cum_time_sec)) %>%
ggline(x='day', y='sum_cum', color = 'group', fill = ' group',
size = 0.5, outlier.shape = NA,
add = c("mean_se"), add.params = list(alpha=0.5),
point.size = 1, linetype = 1, facet.by = "zone", ncol = 4) +
scale_color_manual(values = c('#1064bc', '#afafaf'))
p
To increase panel spacing, we simply use the panel.spacing.x theme element:
p + theme(panel.spacing.x = unit(15, 'mm'))
If you want extra space after the last point, simply change the x axis limits:
p + scale_x_continuous(breaks = 1:5, limits = c(1, 7))
Another option is to use multiple expansions in scale_continuous.
## I am using Allan's carefully produced plot `p`.
## Thanks, Allan +1
p +
scale_x_continuous(breaks = 1:5, expand = expansion(mult = c(0, .4)))

ggplot time series: messed up x axis - 2

This is modified version of this question.
I need to create time series plot for 2 lines for the following data:
# Creating data set
year <- c(rep(2018,4), rep(2019,4), rep(2020,4))
month_1 <- c(2, 3, 7, 8, 6, 10, 11, 12, 5, 7, 8, 12)
avg_dlt_calc <- c(10, 20, 11, 21, 13, 7, 10, 15, 9, 14, 16, 32)
avg_dlt_standard <- c(rep(9,12))
data_to_plot <- data.frame(cbind(year,month_1,avg_dlt_calc,avg_dlt_standard ))
data_to_plot$month_1 <- factor(data_to_plot$month_1, levels=unique(data_to_plot$month_1))
ggplot(data_to_plot,aes(x = as.factor(month_1))) +
geom_line(aes(y = avg_dlt_calc, group = year, colour = "DLT Calculated"), size = 0.5) +
geom_line(aes(y = avg_dlt_standard, group = year, colour = "DLT standard"), size = 0.5) +
geom_point(aes(y = avg_dlt_calc, colour = "DLT Calculated")) +
scale_x_discrete(name = "months", limits = data_to_plot$month_1) +
facet_grid(~year, scales = "free")+
scale_color_manual(name="",
labels = c("DLT Calculated",
"DLT standard"),
values = c( "blue",
"red")) +
theme(legend.position="top",
legend.text = element_text(size = 8))
s = data_to_plot$month_1) +
facet_grid(~year, scales = "free")+
But x-axis looks wrong:
If to plot data without this line:
data_to_plot$month_1 <- factor(data_to_plot$month_1, levels=unique(data_to_plot$month_1))
Then x-axis will still be messy:
I am setting limits for x-axis, but looks like it is not working.
How can I fix it?
I've skipped some lines and features of your plot, but in essence, this is what needs to be changed:
ggplot(data_to_plot, aes(x=month_1))+ # no as.factor
geom_point(aes(y=avg_dlt_calc)) +
geom_line(aes(y=avg_dlt_calc)) +
geom_line(aes(y=avg_dlt_standard), colour='red') +
scale_x_continuous(breaks=1:12, limits=c(1,2)) + # do *not* use scale_x_discrete,
# your x-axis is *continuous*; use breaks-argument to set the ticks.
# note, limits should only have 2 values - upper and lower limit.
facet_grid(~year)
In your code, you used limits = data_to_plot$month_1, but ggplot2 only used the 2 first elements of month_1 - it did not interpret it as a set of acceptable values.

How to add edges/borders to the links in geom_link2 in R?

Is there a way to add an edge/border (not sure of the proper word) to the links created using ggforce::geom_link2 in R? Something similar to points with pch >20.
The issue that I see is that geom_link2 uses col instead of fill in order to define the colour of the link. Therefore I am not sure how the colour of the border could be defined. In turn that makes me think that there is no way to make a border on the link.
Any idea?
Thanks.
EDIT 10/02/21: follow up of the solution from #tjebo.
Here is a reproducible example of the path-crossing issue. The border disappears at the crossing. With 2 paths it is still ok to visualise, but in a complex ordination it gets very messy.
library(ggforce)
#> Loading required package: ggplot2
df <- data.frame( x = c(5, 10, 5, 10), y = c(5, 10, 10, 5), width = c(1, 10, 6, 2), colour = letters[1:4], group = c(1, 1, 2, 2))
ggplot(df) +
geom_path(aes(x = x, y = y, group = group), size = 10, lineend = 'round') +
geom_link2(aes(x = x, y = y, colour = colour, group = group),
size = 5, lineend = 'round', n = 500)
Created on 2021-02-10 by the reprex package (v1.0.0)
Cheeky workaround: Create two geom_link2 plots overlaid. If you want a simple unicolor border, you can as well (and better) use geom_path instead.
Adapted from the example in ?geom_link.
library(tidyverse)
library(ggforce)
lines <- data.frame( x = c(5, 12, 15, 9, 6), y = c(17, 20, 4, 15, 5), xend = c(19, 17, 2, 9, 5), yend = c(10, 18, 7, 12, 1), width = c(1, 10, 6, 2, 3), colour = letters[1:5])
ggplot(lines) +
geom_path(aes(x = x, y = y, group = 1), size = 10, lineend = 'round') +
geom_link2(aes(x = x, y = y, colour = colour, group = 1),
size = 5, lineend = 'round', n = 500)
Created on 2021-02-06 by the reprex package (v0.3.0)

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

Resources