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)
Related
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"
))
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
I don't quite understand the difference between text and label in ggplot2.
For instance:
When I try to convert ggplot2 object to plotly interactive object using label as tooltip, it worked; while I got the Too few points to calculate an ellipse error when using text as tooltip.
Why?
p <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species, label = row.names(iris))) +
geom_point()+
stat_ellipse(aes(fill = Species), geom = "polygon", level = 0.95, alpha = 0.1, show.legend = F)
ggplotly(p)
p2 <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species, text = row.names(iris))) +
geom_point()+
stat_ellipse(aes(fill = Species), geom = "polygon", level = 0.95, alpha = 0.1, show.legend = F)
ggplotly(p2)
The issue is most likely the grouping. I have had no look at the ggplot2 source code but I would guess that (in contrast to the label aes) the text attribute (which is no default ggplot2 aesthetic) is used to group the data, i.e. as you use map the rownames on text you end up with groups containing only one row of data. Hence you get a warning about too few points to draw an ellipse.
To prevent that you could or have to explicitly set the group aes in stat_ellipse:
library(plotly)
p2 <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species, text = row.names(iris))) +
geom_point()+
stat_ellipse(aes(fill = Species, group = Species), geom = "polygon", level = 0.95, alpha = 0.1, show.legend = F)
ggplotly(p2)
Text requires previous label to be shown (as I understand the documentation): Therefore, if one goes to: https://ggplot2.tidyverse.org/reference/geom_text.html; you 'll see that:
With that, you see that the real problem is not the creation of the ellipse, but rather how your geom_text() is interpreted in the function. If you write it as following, both ellipse and row.names appear in the graphic:
p2 <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species, label = row.names(iris))) +
geom_point()+
stat_ellipse(aes(fill = Species), geom = "polygon", level = 0.95, alpha = 0.1, show.legend = F)
p2+geom_text(check_overlap = T)
The result is the following:
Cheers!
I have a scatterplot with 15 groupings. I am using geom_point() with shape = 21 so that I can have fill and color (outline color). I am using black for the outline color to give better contrast between the similar colors in my legend. When I add a stat_ellipse() though, it makes the ellipse outline black.
I want this, with black outlines around the points:
groupings <- paste0("Group", 1:15)
iris$group <- rep(groupings, 10)
iris_plot <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point(aes(Sepal.Length, Sepal.Width, colour = factor(iris$group))) + stat_ellipse(data = iris, aes(color = factor(iris$group)))
iris_plot
But when I add the black outlines around the points, it turns my ellipses black, making them impossible to interpret.
library(RColorBrewer)
groupings <- paste0("Group", 1:15)
iris$group <- rep(groupings, 10)
fill_colors <- scales::hue_pal()(15)
outline_colors <- rep("black", 15)
iris_plot <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point(aes(Sepal.Length, Sepal.Width, colour = factor(iris$group), fill = factor(iris$group)), shape = 21) + stat_ellipse(data = iris, aes(color = factor(iris$group))) + scale_colour_manual(name = "Grouping", labels = sort(unique(factor(iris$group))), values = outline_colors) + scale_fill_manual(name = "Grouping", labels = sort(unique(factor(iris$group))), values = fill_colors)
iris_plot
I do not want a fill color because there is so much overlap between ellipses that it becomes impossible to see anything.
Thank you for your time.
I think you need to pass color outside aes for geom_point, otherwise when you are applying scale_color_manual, it will apply both for geom_point and stat_ellipse:
iris_plot <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point(aes(Sepal.Length, Sepal.Width,fill = group), color = "black", shape = 21) +
stat_ellipse(data = iris, aes(color = group)) +
scale_fill_manual(name = "Grouping", labels = sort(unique(factor(iris$group))), values = fill_colors)+
scale_color_manual(name = "Grouping", values = fill_colors, labels = sort(unique(factor(iris$group))))
iris_plot
Here is a reprex of the issue I'm having:
piris <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, colour = Species)) +
geom_point(aes(fill = Species))
ggMarginal(piris, groupFill = TRUE, groupColour = TRUE)
And the resulting plot is as follows:
I would like to change the points within geom_point to be pch = 21 with fill representing the Species (as in the plot above) but color = "black" so that each point has a black border. My problem is that doing so makes my marginal density plots black:
piris <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, colour = Species)) +
geom_point(aes(fill = Species), pch = 21, color = "black")
ggMarginal(piris, groupFill = TRUE)
ggMarginal seems to be looking at the border color rather than the aes(color). I removed the groupColor from the second plot, because setting it to TRUE just makes one large black density curve. I have a hunch this has something to do with groupColor and groupFill but I simply cannot figure it out. Any help would be greatly appreciated!!
It fills the marginal density plots with colours according groups, however, their borders are black:
piris <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, colour = Species)) +
geom_point(aes(colour=Species)) +
geom_point(pch = 21, colour = "black")
ggMarginal(piris, groupFill = TRUE)