New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

geom_vline messes up geom_line legend, if show_guide = TRUE #1267

Closed
maxheld83 opened this Issue Aug 16, 2015 · 9 comments

Comments

Projects
None yet
6 participants
@maxheld83

maxheld83 commented Aug 16, 2015

Let's say I have some line graph via geom_line and would like to add some geom_vlines as thresholds.
Let's further say that I have several such geom_vlines and would therefore require a legend.

Here's the base layer plot:

library(ggplot2)
data(mpg)

# base plot
g <- ggplot()
g <- g + geom_line(data = mpg, mapping = aes(y = cty, x = year, color = manufacturer), stat = "summary", fun.y = mean)
g

So far, so good:

baseplot


Now let's try and add the threshold via geom_hline with a custom legend:

# add threshold via geom_hline()
g + geom_vline(aes(xintercept = 2004, linetype = "Funny Law"), show_guide = TRUE) + scale_linetype_manual(values = c("Funny Law" = "dashed"))  # screws up all geom_line legends

Not so great, the base-layer legends are all screwed up:

geomhline


Ok, let's see whether we can make this work via geom_linerange() with separate dataframes:

thresholds <- data.frame(threshold = "Funny Law", year = 2004, ymin = 0, ymax = 35)
g + geom_linerange(data = thresholds, mapping = aes(x = year, ymin = ymin, ymax = ymax, linetype = threshold))  # works ok

Works ok, except that the geom_linerange doesn't fill the entire y-height of the plot, but ok:

linerange


Then wouldn't we expect the same approach to work via geom_vline() with a separate dataframe?

# add threshold via geom_hline() WITH separate data
g + geom_vline(data = thresholds, mapping = aes(xintercept = year, linetype = threshold), show_guide = TRUE)  # screws up all geom_line legends

Nope, the same problem with screwed up legends returns:

vlinesep


Bug or my mistake?


May be related:

@maxheld83

This comment has been minimized.

maxheld83 commented Aug 16, 2015

updated, because earlier version was too complicated.

@hadley

This comment has been minimized.

Member

hadley commented Aug 17, 2015

Here's an even simpler example:

df <- data.frame(x = c(1, 2), y = c(1, 2), z = c("a", "b"))

threshold <- data.frame(x = c(1.2, 1.5), name = c("bar", "foo"))
ggplot(df, aes(x, y, colour = z)) + 
  geom_point() + 
  geom_vline(aes(xintercept = x, linetype = name), show.legend = TRUE, data = threshold)

@hadley hadley closed this in e12f8dd Aug 17, 2015

@hadley

This comment has been minimized.

Member

hadley commented Aug 17, 2015

There are a couple of problems here. There's a bug in the legend generation code which means that the legends where inheriting aesthetics when they shouldn't. There's another problem that show.legend = TRUE forces inclusion on every legend. But that problem goes away if geom_vline() defaults to show.legend = NA.

Both these cases now work:

df <- data.frame(x = c(1, 2), y = c(1, 2), z = c("a", "b"))
ggplot(df, aes(x, y, colour = z)) + 
  geom_point() + 
  geom_vline(xintercept = 1.5))

threshold <- data.frame(x = c(1.2, 1.5), name = c("bar", "foo"))
ggplot(df, aes(x, y, colour = z)) + 
  geom_point() + 
  geom_vline(aes(xintercept = x, linetype = name), data = threshold)
@rdcomineor

This comment has been minimized.

rdcomineor commented Feb 22, 2016

Hello, Unfortunately a problem persists in the legends of the lines if you also have to add a horizontal line:
threshold <- data.frame(x = c(1.2, 1.5), name = c("bar", "foo")) ggplot(df, aes(x, y, colour = z)) + geom_point() + geom_vline(aes(xintercept = 1.25, linetype = "dotted"), data = threshold)+geom_hline(aes(yintercept = 1.75, linetype = "1F"), data = threshold)

Do you have a suggestion how to have just a vertical line, or horizontal line and not a cross in the legends? Many thanks

image

@cyberang3l

This comment has been minimized.

cyberang3l commented Dec 1, 2016

Is there any solution to the cross problem demonstrated by @rdcomineor when using both geom_hline and geom_vline?

@ptoche

This comment has been minimized.

ptoche commented Sep 30, 2017

@cyberang3l, I couldn't run the example given by @rdcomineor, but I had a similar problem with geom_linerange() and solved it by inserting show.legend=FALSE: geom_linerange(aes(ymin = y, ymax = x, color = "vline"), show.legend=FALSE) .

The mapping to color still works and this produces a legend for the geom_linerange(), so show.legend=FALSE is not a nuclear option, but it does remove the vertical lines in the legend.

@fmassicano

This comment has been minimized.

fmassicano commented Mar 14, 2018

The problem still persists if you have hline and vline in the same chart.

@ptoche

This comment has been minimized.

ptoche commented Mar 15, 2018

@fmassicano, as this issue is closed, why don't you post a new issue with a working, minimal example. Also, please post screenshot with the reprex package.

https://github.com/tidyverse/reprex

@lock

This comment has been minimized.

lock bot commented Sep 11, 2018

This old issue has been automatically locked. If you believe you have found a related problem, please file a new issue (with reprex) and link to this issue. https://reprex.tidyverse.org/

@lock lock bot locked and limited conversation to collaborators Sep 11, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.