Skip to content

WIP: show.key, a new parameter of guide_legend() to fix #3648 #3649

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

Closed
wants to merge 6 commits into from

Conversation

microly
Copy link
Contributor

@microly microly commented Dec 1, 2019

fix #3648

This is only a pr draft to show my solution to #3648.
The documemtation is lack, and the codes may need improve.
Any comment is welcome!
I will add documemtation and anything needed later.

@microly
Copy link
Contributor Author

microly commented Dec 1, 2019

Some example:

# do nothing, if show.key = NULL, which is the default value.
ggplot() + 
    geom_polygon(aes(x, y, colour = "green"), data.frame(x = c(3, 3, 4), y = c(2, 3, 2)), 
        fill = "grey70", size = 3) +
    geom_line(aes(x, y, colour = "blue"), data.frame(x = c(0, 3), y = c(3, 0))) +
    geom_point(aes(x, y, colour = "red"), data.frame(x = 1, y = 1)) +
    scale_color_identity(guide = guide_legend())

# or
ggplot() + 
    geom_polygon(aes(x, y, colour = "green"), data.frame(x = c(3, 3, 4), y = c(2, 3, 2)), 
        fill = "grey70", size = 3) +
    geom_line(aes(x, y, colour = "blue"), data.frame(x = c(0, 3), y = c(3, 0))) +
    geom_point(aes(x, y, colour = "red"), data.frame(x = 1, y = 1)) +
    scale_color_identity(guide = guide_legend(show.key = NULL))

a

# a new way to fix #3648 
ggplot() + 
    geom_polygon(aes(x, y, colour = "green"), 
                 data_frame(x = c(3, 3, 4), y = c(2, 3, 2)), 
                 fill = "grey70", size = 3) +
    geom_line(aes(x, y, colour = "blue"), data_frame(x = c(0, 3), y = c(3, 0))) +
    geom_point(aes(x, y, colour = "red"), data_frame(x = 1, y = 1)) +
    scale_color_identity(guide = guide_legend(show.key = list(2, 1, 3)))

b

# the legend keys can be high customed!
ggplot() + 
    geom_polygon(aes(x, y, colour = "green"), 
                 data_frame(x = c(3, 3, 4), y = c(2, 3, 2)), 
                 fill = "grey70", size = 3) +
    geom_line(aes(x, y, colour = "blue"), data_frame(x = c(0, 3), y = c(3, 0))) +
    geom_point(aes(x, y, colour = "red"), data_frame(x = 1, y = 1)) +
    scale_color_identity(guide = guide_legend(show.key = list(c(2, 3), c(1, 3), c(1,2,3))))

c

@microly
Copy link
Contributor Author

microly commented Dec 1, 2019

The first example below shows how ggplot2 draws the keys:
It draws all the layers that have a colour mapping to every keys in the same order as the code: 1st: geom_polygon, 2nd: geom_line, 3rd: geom_point.

The users can not control two things:

  • whether to draw the geom of certain layer to one or more keys.
  • if more than one layer geoms were drawn in a key, the order is out of the control of users.

Show.key can give full control of the two things above to users!

# example 1: how ggplot2 works now
ggplot() + 
    geom_polygon(aes(x, y, colour = "green"), data.frame(x = c(3, 3, 4), y = c(2, 3, 2)), 
        fill = "grey70", size = 3) +
    geom_line(aes(x, y, colour = "blue"), data.frame(x = c(0, 3), y = c(3, 0))) +
    geom_point(aes(x, y, colour = "red"), data.frame(x = 1, y = 1)) +
    scale_color_identity(guide = guide_legend())

a

Show.key is a list with length n, which is the number of the breaks of the scale.
The colour scale of the example has three breaks, so the length of show.key is 3.
Every element in the show.key list is a numeric vector.
The first numeric vector is associated with the first key of the legend, and so on.
The numeric vector control the corresponding key in whether to draw the geom of a layer and the order of multiple geoms.

Let's see the example 2 below:

# example 2: how show.key works
ggplot() + 
    geom_polygon(aes(x, y, colour = "green"), 
                 data_frame(x = c(3, 3, 4), y = c(2, 3, 2)), 
                 fill = "grey70", size = 3) +
    geom_line(aes(x, y, colour = "blue"), data_frame(x = c(0, 3), y = c(3, 0))) +
    geom_point(aes(x, y, colour = "red"), data_frame(x = 1, y = 1)) +
    scale_color_identity(guide = guide_legend(show.key = list(c(2, 3), c(1, 3), c(1,2,3))))

c

Firstly, we code the layers with their order in the plot code: 1 geom_polygon, 2 geom_line, 3 geom_point.

Secondly, we can see that show.key is a list of length 3. The first element of show.key, c(2, 3), control the first key of legend. c(2,3) means that the geoms of "2 geom_line" and "3 geom_point" will be drawn in the first key, the drawing order is that "2 geom_line" is first and "3 geom_point" is second.

Generally, if the layer code (e.g. 1 for geom_polygon) is in the nth element of show.key, its geom (e.g. polygon) will be drawn in the nth key of lenged.
If there are multiple geoms in one key (e.g. "2 geom_line" and "3 geom_point"), they will be drawn in the order of the element of show.key (e.g. c(2,3)), which means "2 geom_line" is first and "3 geom_point" is second.

@microly
Copy link
Contributor Author

microly commented Dec 2, 2019

Another example: using show.key in a convenient way.

# base plot
p <- ggplot() + 
    geom_polygon(aes(x, y, colour = "green"), data.frame(x = c(3, 3, 4), y = c(2, 3, 2)), 
                 fill = "grey70", size = 1) +
    geom_line(aes(x, y, colour = "blue"), data.frame(x = c(0, 3), y = c(3, 0)), size = 1) +
    geom_point(aes(x, y, colour = "red"), data.frame(x = 1, y = 1)) +
    scale_color_identity(guide = guide_legend())

p

# code the layers
glyphs <- c(polygon = 1, line = 2, point = 3)

Let's take care the first key: firstly, draw a polygon glyph; secondly, draw a line glyph; at last, draw a point glyph .

p + guides(colour = guide_legend(show.key = list(glyphs["polygon"], NULL, NULL)))

p1

p + guides(colour = guide_legend(show.key = list(glyphs[c("polygon", "line")], NULL, NULL)))

p2

p + guides(colour = guide_legend(show.key = list(glyphs[c("polygon", "line", "point")], 
NULL, NULL)))

p3

@clauswilke clauswilke changed the title show.key: a new parameter of guide_legend() to fix #3648 WIP: show.key, a new parameter of guide_legend() to fix #3648 Dec 2, 2019
@teunbrand teunbrand mentioned this pull request May 9, 2023
@teunbrand
Copy link
Collaborator

Hi @microly, we have found an automated way of extracting the layer-key interaction so we'll use that instead of this PR. Thank you for testing out solutions and preparing this PR to address the issue; we're glad that you were willing to contribute.

@teunbrand teunbrand closed this Nov 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement smart merging of guides so inappropriate key glyphs are omitted
2 participants