I don't understand why the dots for ID 2,6,8,10 won't align vertically like they do in 1,3,4,7,9.
The offset is affected by stackratio, but why doesn't it affect all the groups?
ggplot(sleep,
aes(x=ID,fill=group,y=extra))+
geom_dotplot(binaxis = 'y',
method="histodot",
stackgroups = TRUE,
binpositions="bygroup",
stackratio=1,
binwidth=0.1,
stackdir = "center",
dotsize = 3)
Another example is
ggplot(mtcars, aes(x = factor(am),fill = factor(cyl), y = mpg)) +
geom_dotplot(binaxis = "y",stackgroups = TRUE, stackdir = "center", binpositions="all")
Here stackgroups = TRUE makes everything offset weirdly.
Can something be done here, or is there another way to get the samme?
It seems that geom_dotplot calculates "dodge" positions as if all the dots were in one group and then plots them in each group.
I found work around.
Here i make a plot and color the dots myself. This ggplot can not make a legend for, so I make another plot that was the right legend.
Then use plot_grid to make my final plot.
It is important to setkey right, or the plot will be colored incorrect.
mycars <- as.data.table(mtcars)
mycars[cyl=="4",mycol:="red"][cyl=="6",mycol:="green"][cyl=="8",mycol:="blue"]
setkey(mycars,am,mpg)
myplot <- ggplot(mycars, aes(x = factor(am), y = mpg)) +
geom_dotplot(binaxis = "y",
fill=mycars$mycol,
stackratio=1,
binwidth=0.7, drop=FALSE,
stackdir = "center",
dotsize = 1)
lplot <- ggplot(mtcars, aes(x = factor(am),fill = factor(cyl), y = mpg))+
geom_dotplot(binaxis = "y",stackgroups = TRUE)+
scale_fill_manual(values=c("red","green", "blue"))
mylegend <- get_legend(lplot)
plot_grid(myplot,mylegend,ncol=2,rel_widths = c(6,1))
Plot
I cannot tell you what's the issue when using the geom_dotplot function, but you can get what you want by using geom_point and the option position = position_dodge2(). Inside the function position_dodge2() you can use width to control the position of each point. See the full code below:
library(ggplot2)
ggplot(sleep,
aes(x=ID,fill=group,y=extra))+
geom_point(
size=3,
pch = 21,
position = position_dodge2(width=c(rep(0.00001,4),
0.2,
rep(0.00001,5)))
) +
scale_y_continuous(limits = c(-2,6)) +
theme_classic() +
theme(panel.grid.major.x = element_line(color="gray",
linetype = "dashed"))
The result:
Update
We can have different alignments within the same X. For instance, when ID=1 I can move the point for group 2 while maintaining the point for group 1:
Code:
library(ggplot2)
ggplot(sleep,
aes(x=ID,fill=group,y=extra))+
geom_point(
size=3,
pch = 21,
position = position_dodge2(width=c(0.7,
rep(0.00001,3),
0.2,
rep(0.00001,5),
0.00001,
rep(0.00001,3),
0.2,
rep(0.00001,5)))
) +
scale_y_continuous(limits = c(-2,6)) +
theme_classic() +
theme(panel.grid.major.x = element_line(color="gray",
linetype = "dashed"))
Related
I am trying to add labels in line graph but am unable to do so.
I want to add lable such that blue line mentiones 'model_1'; red line mentioned 'model_2' and darkgreen line mentioned 'model_3'
Attaching the code below
p1 <- ggplot(data = Auto, aes(x = horsepower, y = mpg)) +
geom_point() +
geom_line(aes(y = fitted(lm_mpg_1)), color = "blue", size = 1) +
geom_line(aes(y = fitted(lm_mpg_2)), color = "red", size = 1) +
geom_line(aes(y = fitted(lm_mpg_3)), color = "darkgreen", size = 1)
I have tried to use geom_text, geom_label and annotate function however they give me error.
The code I tried was:
p1 + geom_text(label = c('model_1','model_2','model_3'))
You don't have any data. You can use dput to share your data. In the meanwhile I have used mtcars as an example below:
# library
library(ggplot2)
# Keep 30 first rows in the mtcars natively available dataset
data=head(mtcars, 30)
# 1/ add text with geom_text, use nudge to nudge the text
ggplot(data, aes(x=wt, y=mpg)) +
geom_point() + # Show dots
geom_text(
label=rownames(data),
nudge_x = 0.25, nudge_y = 0.25,
check_overlap = T
)
ggplot(data, aes(x=wt, y=mpg)) +
geom_point() + # Show dots
geom_label(
label=rownames(data),
nudge_x = 0.25, nudge_y = 0.25,
check_overlap = T
)
p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point()
p + annotate("text", x = 4, y = 25, label = "Some text")
I am trying to create a figure with ggplot and would like to add category names between colorbar breaks (values). I am using a graduated colorbar using the scale_color_fermenter function, which I think makes it a bit tricky to do this.
Below is an example code
library('ggplot2')
ggplot(mtcars, aes(x=mpg, y=carb, color=disp)) +
geom_point(size=3)+
scale_color_fermenter(breaks = c(100,300,400), palette = "Blues") #graduate colorbar
The resulting figure looks like this
I want to add categories (A, B, C, etc.) between the colorbar breaks (i.e., create categories for disp), such that
0<=A<100
100<=B<300
300<=C<400
400<=D<500
The resulting figure looks like this (or similar)
I know I can add extra breaks and change the label. Something like the following
scale_color_fermenter(breaks=c(50,100,200,300,350,400,450,500),
labels=c('A','100','B','300','C','400','D','500'))
But this would mess up the colorbar class (i.e., colorbar will have more colors), which is something I do not want.
Basically the same approach as by #zephryl but with some additional styling and fiddling and using ggtext::element_markdown just in case you want some additional styling for the text labels.
Using lineheight I add some padding between the tick and the category labels.
Using vjust I shift the labels so that the position of the tick labels corresponds approximately to the boundaries of the legend keys.
library("ggplot2")
mylabels <- function(x) {
paste0(
c(rep("", length(x) - 1), paste0("<span style='color: red'>", LETTERS[length(x) + 1], "</span><br>")),
x,
"<br><span style='color: red'>", LETTERS[seq_along(x)], "</span>"
)
}
ggplot(mtcars, aes(x = mpg, y = carb, color = disp)) +
geom_point(size = 3) +
scale_color_fermenter(breaks = c(100, 300, 400), labels = mylabels, palette = "Blues") +
theme(legend.text = ggtext::element_markdown(vjust = c(.85, .85, .55), lineheight = 1.25))
How about:
library(ggplot2)
ggplot(mtcars, aes(x = mpg, y = carb, color = disp)) +
geom_point(size = 3)+
scale_color_fermenter(
breaks = c(100,300,400),
labels = c("B\n100\nA", "C\n300\n", "D\n400\n"),
palette = "Blues"
)
Created on 2022-10-27 with reprex v2.0.2
An alternative is to draw the letters on as annotations:
ggplot(mtcars, aes(mpg, carb, color = disp)) +
geom_point(size = 3) +
scale_color_fermenter(breaks = c(100, 300, 400)) +
coord_cartesian(clip = "off") +
annotation_custom(grid::textGrob(c("A", "B", "C", "D"),
x = 1.02, y = seq(0.39, 0.57, 0.058))) +
theme(legend.box.margin = margin(10, 10, 10, 10))
I am trying to make a figure that will have density plots on the bottom and corresponding boxplots above the density plots. My density plots and boxplots are filled/colored by a categorical variable. I cannot figure out a way to get the boxplots to be above the density plots and also dodged. This is what I've been able to get so far:
d <- mtcars
d$cyl <- as.factor(d$cyl)
fig <- ggplot(data = d) +
geom_density(aes(x = mpg, fill = cyl),
position = "dodge",
na.rm = TRUE) +
geom_boxplot(aes(x = mpg, color = cyl),
position = ggstance::position_dodgev(height = 1),
width = .05, show.legend = FALSE,
na.rm = TRUE) +
facet_grid(~am, scales = "free_x") +
scale_fill_brewer(palette = "Set2") +
scale_color_brewer(palette = "Set2") +
theme_minimal() +
guides(color = FALSE, fill = FALSE)
fig
But, as you can see, this does not uniformly move the boxplots above the density plots. I've also used
geom_boxplot(aes(x = mpg, color = cyl),
position = position_nudge(x = 0, y = .3),
width = .05, show.legend = FALSE,
na.rm = TRUE) +
but I end up having my boxplots overlap (they are no longer vertically dodged). Basically, I'm looking for a way to set a vertical height for my group of boxplots so they're above my density plots AND keep them vertically dodged from one another. Any suggestions are much appreciated.
Map the value you want your boxes to be centered around to y, inside the aes for geom_boxplot. E.g.:
ggplot(data = d) +
geom_density(aes(x = mpg, fill = cyl)) +
geom_boxplot(aes(x = mpg, color = cyl, y = 1),
position = ggstance::position_dodgev(height = 0.2),
width = .05, show.legend = FALSE) +
facet_grid(~am, scales = "free_x") +
scale_fill_brewer(palette = "Set2") +
scale_color_brewer(palette = "Set2") +
theme_minimal() +
guides(color = FALSE, fill = FALSE)
Also, don't try to dodge geom_density.
I am trying to make a bar chart with line plots as well. The graph has created fine but the legend does not want to add the line plots to the legend.
I have tried so many different ways of adding these to the legend including:
ggplot Legend Bar and Line in Same Graph
None of which have worked. show.legend also seems to have been ignored in the geom_line aes.
My code to create the graph is as follows:
ggplot(first_q, aes(fill = Segments)) +
geom_bar(aes(x= Segments, y= number_of_new_customers), stat =
"identity") + theme(axis.text.x = element_blank()) +
scale_y_continuous(expand = c(0, 0), limits = c(0,3000)) +
ylab('Number of Customers') + xlab('Segments') +
ggtitle('Number Customers in Q1 by Segments') +theme(plot.title =
element_text(hjust = 0.5)) +
geom_line(aes(x= Segments, y=count) ,stat="identity",
group = 1, size = 1.5, colour = "darkred", alpha = 0.9, show.legend =
TRUE) +
geom_line(aes(x= Segments, y=bond_count)
,stat="identity", group = 1, size = 1.5, colour = "blue", alpha =
0.9) +
geom_line(aes(x= Segments, y=variable_count)
,stat="identity", group = 1, size = 1.5, colour = "darkgreen",
alpha = 0.9) +
geom_line(aes(x= Segments, y=children_count)
,stat="identity", group = 1, size = 1.5, colour = "orange", alpha
= 0.9) +
guides(fill=guide_legend(title="Segments")) +
scale_color_discrete(name = "Prod", labels = c("count", "bond_count", "variable_count", "children_count)))
I am fairly new to R so if any further information is required or if this question could be better represented then please let me know.
Any help is greatly appreciated.
Alright, you need to remove a little bit of your stuff. I used the mtcars dataset, since you did not provide yours. I tried to keep your variable names and reduced the plot to necessary parts. The code is as follows:
first_q <- mtcars
first_q$Segments <- mtcars$mpg
first_q$val <- seq(1,nrow(mtcars))
first_q$number_of_new_costumers <- mtcars$hp
first_q$type <- "Line"
ggplot(first_q) +
geom_bar(aes(x= Segments, y= number_of_new_costumers, fill = "Bar"), stat =
"identity") + theme(axis.text.x = element_blank()) +
scale_y_continuous(expand = c(0, 0), limits = c(0,3000)) +
geom_line(aes(x=Segments,y=val, linetype="Line"))+
geom_line(aes(x=Segments,y=disp, linetype="next line"))
The answer you linked already gave the answer, but i try to explain. You want to plot the legend by using different properties of your data. So if you want to use different lines, you can declare this in your aes. This is what get's shown in your legend. So i used two different geom_lines here. Since the aes is both linetype, both get shown at the legend linetype.
the plot:
You can adapt this easily to your use. Make sure you using known keywords for the aesthetic if you want to solve it this way. Also you can change the title names afterwards by using:
labs(fill = "costum name")
If you want to add colours and the same line types, you can do customizing by using scale_linetype_manual like follows (i did not use fill for the bars this time):
library(ggplot2)
first_q <- mtcars
first_q$Segments <- mtcars$mpg
first_q$val <- seq(1,nrow(mtcars))
first_q$number_of_new_costumers <- mtcars$hp
first_q$type <- "Line"
cols = c("red", "green")
ggplot(first_q) +
geom_bar(aes(x= Segments, y= number_of_new_costumers), stat =
"identity") + theme(axis.text.x = element_blank()) +
scale_y_continuous(expand = c(0, 0), limits = c(0,3000)) +
geom_line(aes(x=Segments,y=val, linetype="solid"), color = "red", alpha = 0.4)+
geom_line(aes(x=Segments,y=disp, linetype="second"), color ="green", alpha = 0.5)+
scale_linetype_manual(values = c("solid","solid"),
guide = guide_legend(override.aes = list(colour = cols)))
How can I can remove the letter 'a' from the legend generated by this code? If I remove the geom_text, then the 'a' letter will not show in the legend. I want to keep geom_text, though.
ggplot(data = iris, aes(x = Sepal.Length, y=Sepal.Width,
shape = Species, colour = Species)) +
geom_point() +
geom_text(aes(label = Species))
Set show.legend = FALSE in geom_text:
ggplot(data = iris,
aes(x = Sepal.Length, y = Sepal.Width, colour = Species,
shape = Species, label = Species)) +
geom_point() +
geom_text(show.legend = FALSE)
The argument show_guide changed name to show.legend in ggplot2 2.0.0 (see release news).
Pre-ggplot2 2.0.0:
With show_guide = FALSE like so...
ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width , colour = Species,
shape = Species, label = Species ), size = 20) +
geom_point() +
geom_text(show_guide = FALSE)
We can use guide_legend(override.aes = aes(...)) to hide the 'a' in the legend.
Below is a short example of how you might use guide_legend()
library(ggrepel)
#> Loading required package: ggplot2
d <- mtcars[c(1:8),]
p <- ggplot(d, aes(wt, mpg)) +
geom_point() +
theme_classic(base_size = 18) +
geom_label_repel(
aes(label = rownames(d), fill = factor(cyl)),
size = 5, color = "white"
)
# Let's see what the default legend looks like.
p
# Now let's override some of the aesthetics:
p + guides(
fill = guide_legend(
title = "Legend Title",
override.aes = aes(label = "")
)
)
Created on 2019-04-29 by the reprex package (v0.2.1)
I had a similar problem. Simon's solution worked for me but a slight twist was required. I did not realise that I need to add "show_guide = F" to geom_text's arguments, rather than replace with it the existing arguments - which is what Simon's solution shows. For a ggplot2 noob like me this was not that obvious. A proper example would have used the OP's code and just added the missing argument like this:
..
geom_text(aes(label=Species), show_guide = F) +
..
Like Nick said
the following code would still produce the error:
geom_text(aes(x=1,y=2,label="",show_guide=F))
whereas:
geom_text(aes(x=1,y=2,label=""),show_guide=F)
outside the aes argument eliminates the a over the legend
I had a similar problem, with an 'a' appearing behind different coloured points I was trying to label with geom_text_repel. To remove the 'a', so that it would just show the point without the 'a' behind it, I had to add show.legend=FALSE as an argument in geom_text_repel.
Hope that makes sense to anyone who might be labouring with the same issue!
You can also use show.legend = FALSE in the arguments of geom_label_repel() to remove the "a" in the legend.
So, instead of
ggplot(d, aes(wt, mpg)) +
geom_point() +
theme_classic(base_size = 18) +
geom_label_repel(
aes(label = rownames(d), fill = factor(cyl)),
size = 5, color = "white"
)+ guides(
fill = guide_legend(
title = "Legend Title",
override.aes = aes(label = "")
)
)
you can do,
ggplot(d, aes(wt, mpg)) +
geom_point() +
theme_classic(base_size = 18) +
geom_label_repel(
aes(label = rownames(d), fill = factor(cyl)),
size = 5, color = "white",
show.legend = FALSE )