Reputation: 193
I created this scatter plot with ggplot
and as you can see I don't manage to create a corresponding legend to the plot:
I would have like as well, if possible, to put the legend for the dashed line "Seuil" closer to these points.
Here is my code:
ggplot(tst_formule, aes(x=nom_graph, y = value, shape = BRI_type, col = factor(BRI_type))) +
geom_point(size = 4) +
scale_shape_manual("", values = c( 15, 17)) +
scale_colour_manual(values=c("grey20", "gray54"), # légende
name ="Légende",
breaks=c("BRI_adi_moy_guide", "BRI_adi_moy_Sandrine"),
labels=c("Méthode par transects", "Méthode par sous-transects")) +
geom_text(aes(label = value, vjust = -0.5, hjust= -0.1), show.legend = FALSE) + # etiquettes
geom_hline(aes(yintercept = 0.004, linetype = "Seuil"), colour= 'black') +
scale_linetype_manual("", values = c(2), guide = guide_legend(override.aes = list(color = c("black")))) +
scale_x_discrete("\nTronçons\n") +
scale_y_continuous("\nValeur du BRI*\n", limits = c(0,0.025)) +
theme(axis.text.x = element_text(size = 11),
axis.text.y = element_text(size = 11),
legend.text = element_text(size = 11),
plot.margin = unit(c(0.2,0.2,0.2,0.2), "cm"))
I read several posts and tried different solutions but it doesn't work, I'm still new to ggplot and I think my syntax may be wrong for the legend...
Here is a dput()
of my data:
structure(list(Riviere = c("Durance", "Durance", "Roya", "Drac",
"Drac", "Durance", "Durance", "Roya", "Drac", "Drac"), Troncon = c("La Brillanne",
"Les Mées", "Basse vallée", "St Bonnet", "St Bonnet", "La Brillanne",
"Les Mées", "Basse vallée", "St Bonnet", "St Bonnet"), Annee = c(2017,
2017, 2018, 2011, 2018, 2017, 2017, 2018, 2011, 2018), nom_graph = c("La Brillane 2017 \nDurance",
"Les Mées 2017 \nDurance", "Roya 2018", "St Bonnet 2011 \nDrac",
"St Bonnet 2018 \nDrac", "La Brillane 2017 \nDurance", "Les Mées 2017 \nDurance",
"Roya 2018", "St Bonnet 2011 \nDrac", "St Bonnet 2018 \nDrac"
), BRI_type = c("BRI_adi_moy_Sandrine", "BRI_adi_moy_Sandrine",
"BRI_adi_moy_Sandrine", "BRI_adi_moy_Sandrine", "BRI_adi_moy_Sandrine",
"BRI_adi_moy_guide", "BRI_adi_moy_guide", "BRI_adi_moy_guide",
"BRI_adi_moy_guide", "BRI_adi_moy_guide"), value = c(0.0037,
0.0024, 0.0013, 0.0239, 0.0038, 0.0028, 0.0017, 0.0009, 0.02,
0.0031)), row.names = c(NA, -10L), class = "data.frame")
Any help is welcomed!
Upvotes: 0
Views: 308
Reputation: 13863
First of all: Thanks so much for posting your dataset via dput
. It really helps to answer your question and is really appreciated.
The basic idea is to let ggplot
create and combine legends, which it tries to do intelligently. To create a legend in the first place, you put the parameter into an aesthetic (aes()
), which you've done already. In your case, you want to combine the shape=
and color=
aesthetic.
First of all, make sure they are pointing to the right thing. In your case, the references are not the same (shape= BRI_type
, whereas color= factor(BRI_type)
), but to ggplot
, this is the same thing. The character vector tst_formule$BRI_type
will be converted to a factor during the creation of the plot in order to separate shape=
based on the levels of that factor. Bottom line, you can remove factor(BRI_type)
and just use BRI_type
; however, the end result is the same. It's just better practice.
Remember I mentioned that ggplot
tries to combine legends automatically? Well, since color=
and shape=
are pointed to the same factor (BRI_type
, which gets factored before plotting), by default, you will get a combined legend. You can see this for yourself by removing scale_color_manual
and scale_shape_manual
from your original code:
ggplot(tst_formule, aes(x=nom_graph, y = value, shape = BRI_type, col = BRI_type)) +
geom_point(size = 4) +
geom_text(aes(label = value, vjust = -0.5, hjust= -0.1), show.legend = FALSE) + # etiquettes
geom_hline(aes(yintercept = 0.004, linetype = "Seuil"), colour= 'black') +
scale_linetype_manual("", values = c(2), guide = guide_legend(override.aes = list(color = c("black")))) +
scale_x_discrete("\nTronçons\n") +
scale_y_continuous("\nValeur du BRI*\n", limits = c(0,0.025)) +
theme(axis.text.x = element_text(size = 11),
axis.text.y = element_text(size = 11),
legend.text = element_text(size = 11),
plot.margin = unit(c(0.2,0.2,0.2,0.2), "cm"))
The general rule is in order to preserve the legend combination, if you change one aspect of one legend, you have to make the same simultaneous change to the other legend. This concept is demonstrated well in this post. So in the solution, I'll change both legends concurrently.
Additionally, you will see I've done the following in order to adjust the spacing of the legends:
Changed both scale_shape_
and scale_color_
calls to use the same parameters for name=
, and labels=
. The values=
parameters for both is sent a list
item that contains the same named labels
from your data, but with different values. Note that if you alter any one of these parameters, you will get two legends, so it's important to change all at the same time.
legend.spacing.y
is used to adjust the spacing between the shape/color
and linetype
legends
legend.margin
is used to set the margin around each legend (allows them to get closer without clipping).
legend.title
A consequence to making the spacing smaller is that the title gets "squished" near the keys. I add a margin her to ensure there is space between the legend title and the keys.
I set the name=
of the linetype
legend to be NULL
instead of ""
. If you use ""
, it's blank, but it's still a character, so still takes up space. That means that when you move the legend up, you start to get clipping of ""
with the upper legend. it's better to remove it altogether by setting it to be NULL
.
Here's the code and resulting plot:
ggplot(tst_formule, aes(x=nom_graph, y = value, shape = BRI_type, col = BRI_type)) +
geom_point(size = 4) +
scale_shape_manual(
values=list("BRI_adi_moy_guide"=15, "BRI_adi_moy_Sandrine"=17),
name ="Légende",
labels=c("Méthode par transects", "Méthode par sous-transects")) +
scale_colour_manual(
values=list("BRI_adi_moy_guide"="grey20", "BRI_adi_moy_Sandrine"="gray54"),
name ="Légende",
labels=c("Méthode par transects", "Méthode par sous-transects")) +
geom_text(aes(label = value, vjust = -0.5, hjust= -0.1), show.legend = FALSE) + # etiquettes
geom_hline(aes(yintercept = 0.004, linetype = "Seuil"), colour= 'black') +
scale_linetype_manual(
name=NULL, values = c(2),
guide = guide_legend(override.aes = list(color = c("black")))) +
scale_x_discrete("\nTronçons\n") +
scale_y_continuous("\nValeur du BRI*\n", limits = c(0,0.025)) +
theme(axis.text.x = element_text(size = 11),
axis.text.y = element_text(size = 11),
legend.text = element_text(size = 11),
plot.margin = unit(c(0.2,0.2,0.2,0.2), "cm"),
legend.spacing.y = unit(0.1, 'cm'),
legend.margin = margin(0,0,0,0, 'pt'),
legend.title = element_text(margin=margin(0,0,0.1,0, 'cm'))
)
Upvotes: 1