Dodge Effect with geom_segment [duplicate] - r

I did something like this with my data, but despite the transparency the segments are hard to visualise (my data has lot less number of segments than the example below) to see their beginning and end.
require(ggplot2)
ggplot(iris, aes(x = Petal.Length, xend = Petal.Width,
y = factor(Species), yend = factor(Species),
size = Sepal.Length)) +
geom_segment(alpha = 0.05) +
geom_point(aes(shape = Species))
Came across this solution, but the lines are criss-crossed. Is there a way to make the jitter produce parallell lines with the points at the tips? I have tried position_dodge instead of position_jitter, but it requires ymax. Can ymax be integrated at all for use with geom_segment?
ggplot(iris, aes(x = Petal.Length, xend = Petal.Width,
y = factor(Species), yend = factor(Species))) +
geom_segment(position = position_jitter(height = 0.25))+
geom_point(aes(size = Sepal.Length, shape = Species))

As far as I know, geom_segment does not allow jittering nor dodging. You can add jittering to the relevant variable in the data frame, then plot the jittered variable. In your example, the factor is converted to numeric, then the labels for the levels of the factor are added to the axis using scale_y_continuous.
library(ggplot2)
iris$JitterSpecies <- ave(as.numeric(iris$Species), iris$Species,
FUN = function(x) x + rnorm(length(x), sd = .1))
ggplot(iris, aes(x = Petal.Length, xend = Petal.Width,
y = JitterSpecies, yend = JitterSpecies)) +
geom_segment()+
geom_point(aes(size=Sepal.Length, shape=Species)) +
scale_y_continuous("Species", breaks = c(1,2,3), labels = levels(iris$Species))
But it seems geom_linerange allows dodging.
ggplot(iris, aes(y = Petal.Length, ymin = Petal.Width,
x = Species, ymax = Petal.Length, group = row.names(iris))) +
geom_point(position = position_dodge(.5)) +
geom_linerange(position = position_dodge(.5)) +
coord_flip()

The position argument of geom_segment might be helpful for you, see Slightly change geom_segment's position of x only, but keep position of xend constant

Related

get legend for two different data sets in ggplot

I am trying to create a legend from two different data sets. An example as below
ggplot(data = mtcars,aes(x = mpg, y = wt))+
geom_point(aes(colour = drat))+
geom_line(aes(colour = drat))+
geom_point(data = iris, aes(x = Sepal.Width, y = Petal.Length))+
geom_line(data = iris, aes(x = Sepal.Width, y = Petal.Length),linetype = "dashed")+
scale_color_gradientn(colours=c('red','yellow','green'))
In the first data (mtcars) the color is according to a certain column value (drat). But in the second data (iris) it is just x and y points. How can I get line as the two lines as legend in addition to the color legend which is already present.
Easiest way is to pass names to linetype within the aes() calls. The names become the legend labels. You can then use scale_linetype_manual to set linetypes there:
library(ggplot2)
ggplot(data = mtcars,aes(x = mpg, y = wt))+
geom_point(aes(colour = drat))+
geom_line(aes(colour = drat, linetype = "Cars"))+
geom_point(data = iris, aes(x = Sepal.Width, y = Petal.Length))+
geom_line(data = iris, aes(x = Sepal.Width, y = Petal.Length,
linetype = "Iris"))+
scale_color_gradientn(colours=c('red','yellow','green')) +
scale_linetype_manual(values = c(
"Cars" = "solid",
"Iris" = "dotted"
))

R ggplot geom_label rotate label

I have a plot with labels. I wanted the bounding background box on the label so I switched from using geom_text to geom_label. When I was using the geom_text option I had my angle = 90. Is there a way to do that with geom_label? Or an alternative method to labeling with a background?
Here is some sample code to play with:
ggplot(data = iris,
aes(x = Sepal.Width, y = Petal.Length)) + geom_point(size = 10)+
geom_label(data = iris,
aes(x = Sepal.Width, y = Petal.Length, label = Species),alpha=0.5)
According to the docs
Currently geom_label() does not support the check_overlap argument or the angle aesthetic.
An alternative would be to use ggtext::geom_richtext:
library(ggplot2)
ggplot(
data = iris,
aes(x = Sepal.Width, y = Petal.Length)
) +
geom_point(size = 10) +
ggtext::geom_richtext(aes(label = Species), alpha = 0.5, angle = 90)

How to add a legend manually by ggplots?

For a task I have to make a plot with ggplots with a correct legend.
Well my plot is good, but my legend is not as I want.
I want in my legend a specifing that the triangle is for Sepal, and the plus for Petal.
Can someone help me?
Below is my script.
ggplot(data=iris)+
geom_point(aes(x = Sepal.Length, y = Sepal.Width, color=group), shape=2)+
geom_point(aes(x = Petal.Length, y = Petal.Width, color=group), shape=3)+
xlab("lengte (cm)")+
ylab("breedte (cm)")+
theme(legend.justification=c("left","top"))
I had to make a group variable, but here is an example:
iris$group <- as.factor(sample(c(0,1), nrow(iris), replace=TRUE))
ggplot(data=iris)+
geom_point(aes(x = Sepal.Length, y = Sepal.Width, color=group, shape="Sepal"))+
geom_point(aes(x = Petal.Length, y = Petal.Width, color=group, shape="Petal"))+
xlab("lengte (cm)")+
ylab("breedte (cm)")+
theme(legend.justification=c("left","top"))+
scale_shape_manual(values = c(2,3))

ggplot: adding a frequency plot over a percentage plot

I am interested in doing a plot showing percentages by group.
something like this:
data(iris)
ggplot(iris,
aes(x = Sepal.Length, group = factor(Species), fill = factor(Species))) +
geom_histogram(position = "fill")+theme_bw()
however, I would also like to plot a histogram showing the frequency distribution on top of this graph.
something like the plot below.
ggplot(iris,aes(x = Sepal.Length)) +
geom_histogram()+theme_bw()
Does anyone know how to do this?
Note I know how to do a frequency plot by group: ggplot(iris,aes(x = Sepal.Length, group = factor(Species), fill = factor(Species))) + geom_histogram()+theme_bw(). But this is not what I want. Rather I would like a small frequency distribution at the bottom of the percentage plot presented at the beginning.
Thank you very much
Something like this?
library(gridExtra)
p1 <- ggplot(iris,
aes(x = Sepal.Length,
group = factor(Species),
fill = factor(Species))) +
geom_histogram(position = "fill") +
theme_bw() +
theme(legend.position = "top")
p2 <- ggplot(iris,aes(x = Sepal.Length,
group = factor(Species),
fill = factor(Species))) +
geom_histogram() +
theme_bw() +
theme(legend.position = "none")
grid.arrange(p1, p2,
heights = c(4, 1.5))
Edit: So you are looking for this then? Note that in this case the absolute values of the smaller histogram become meaningless since they were scaled down to be ~25% of the vertical chart range.
ggplot() +
geom_histogram(data = iris,
aes(x = Sepal.Length,
group = factor(Species),
fill = factor(Species)),
position = "fill",
alpha = 1) +
geom_histogram(data = iris,
aes(x = Sepal.Length,
y = ..ncount.. / 4),
alpha = 0.5,
fill = 'black')

Combine and merge legends in ggplot2 with patchwork (discrete/categorical data)

I arranged 3 ggplot2 plots into a single figure by using the functionality of package patchwork. I tried to collect the legends and they appeared one next to the other. But still, they are 3 separate legends and I expected a single legend. So how can I merge the legends that contain identical values of the same factor variable into a single legend?
Notes:
And I do not want to remove the legends of separate plots by using, e.g., theme(legend.position = "none") in case some additional factor level appears. I expect patchwork specific solution.
A similar question was answered in Combine and merge legends in ggplot2 with patchwork but the data was continuous. And in my case, I have categorical data.
The code:
library(ggplot2)
library(patchwork)
iris_1 <-
ggplot(iris, aes(x = Sepal.Length, fill = Species, color = Species)) +
geom_density(alpha = 0.3, adjust = 1.5)
iris_2 <-
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
geom_point()
iris_3 <-
ggplot(iris, aes(x = Species, y = Sepal.Width, fill = Species)) +
geom_boxplot()
(iris_1 + iris_2 + iris_3) + plot_layout(guides = "collect")
Created on 2020-10-14 by the reprex package (v0.3.0)
Update
I tried using the same aesthetic mappings (fill = Species and color = Species) as it was proposed in the comments below but it had no effect:
library(tidyverse)
library(patchwork)
iris_1 <-
ggplot(iris, aes(x = Sepal.Length, color = Species, fill = Species)) +
geom_density(alpha = 0.3, adjust = 1.5)
iris_2 <-
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species, fill = Species)) +
geom_point()
iris_3 <-
ggplot(iris, aes(x = Species, y = Sepal.Width, color = Species, fill = Species)) +
geom_boxplot(color = "black")
(iris_1 + iris_2 + iris_3) + plot_layout(guides = "collect")
Created on 2020-10-14 by the reprex package (v0.3.0)
Unfortunately setting the same aes is only one condition. patchwork will merge legends only if they are identical. Therefore we have to ensure that the legends are the same for each plot. To this end I add a guides layer which makes the look of each legend the same by setting color, shape, size and alpha. Additionally we have to choose the same glyph for each geom using argument key_glyph. After these adjustments the three legends get merged into one.
library(ggplot2)
library(patchwork)
g <- guides(fill = guide_legend(override.aes = list(color = scales::hue_pal()(3),
shape = c(16, 16, 16),
size = c(1, 1, 1),
alpha = c(1, 1, 1)),))
iris_1 <-
ggplot(iris, aes(x = Sepal.Length)) +
geom_density(aes(fill = Species, color = Species), key_glyph = "point", alpha = 0.3, adjust = 1.5) +
g
iris_2 <-
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point(aes(fill = Species, color = Species), key_glyph = "point") +
g
iris_3 <-
ggplot(iris, aes(x = Species, y = Sepal.Width)) +
geom_boxplot(aes(fill = Species, color = Species), key_glyph = "point") +
scale_color_manual(values = c("black", "black", "black")) +
g
(iris_1 + iris_2 + iris_3) + plot_layout(guides = "collect")

Resources