Skip to content
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

purpose of validate_element? #1240

Closed
baptiste opened this issue Aug 5, 2015 · 6 comments
Closed

purpose of validate_element? #1240

baptiste opened this issue Aug 5, 2015 · 6 comments

Comments

@baptiste
Copy link
Contributor

@baptiste baptiste commented Aug 5, 2015

validate_element makes it hard to use a custom grob instead of the default theme element, say, replacing a facet strip text with a grob that handles multiple lines and plotmath expressions, or an axis with an arrow, etc.

Is there a strong argument to maintain this internal check?

@hadley
Copy link
Member

@hadley hadley commented Aug 5, 2015

Yes, because otherwise if you supply the wrong type of grob you'll get an obscure error when the plot is drawn, not when you set the theme. The prior version of themes let you have custom grobs, but no one ever used its not a common request.

But it's just a test for inheritance, so if your custom grob implements the text protocol, why don't you inherit from element_text?

@hadley hadley closed this Aug 5, 2015
@hadley
Copy link
Member

@hadley hadley commented Aug 5, 2015

In other words, make it work like the other element functions:

library(ggplot2)

element_custom <- function() {
  structure(list(), class = c("element_custom", "element_text"))
}

element_grob.element_custom <- function(element, label="", ...)  {
  disect <- strsplit(label, "\\n")[[1]]
  g1 <- gridExtra::tableGrob(as.matrix(disect), 
    parse = TRUE,
    theme = gridExtra::theme.list(
      gpar.corefill = grid::gpar(fill = NA, col = NA), 
      core.just = "center")
  )
  grid::gTree(
    children = grid::gList(g1), 
    height = grid::grobHeight(g1), 
    cl = "custom_strip"
  )
}
# gTrees don't know their size and ggplot would squash it, so give it room
grobHeight.custom_strip <- function(x, ...) x$height
heightDetails.custom_axis <- function(x, ...) x$height

title <- c(
  "First*line \n italic('see that second')", 
  "this~is~boring",
  "integral(f(x)*dx, a, b)"
)

iris2 <- iris
iris2$Species <- factor(iris$Species, labels = title)
ggplot(iris2, aes(Sepal.Length, Sepal.Width)) +
  geom_line() + facet_grid(.~Species) +
  theme(strip.text.x = element_custom())

@hadley
Copy link
Member

@hadley hadley commented Aug 5, 2015

Ooh, but that doesn't work because of the way themes elements are merged. This works, but is a bit clunky:

ggplot(iris2, aes(Sepal.Length, Sepal.Width)) +
  geom_line() + facet_grid(. ~ Species) + 
  (theme_grey() %+replace% theme(strip.text.x = element_custom()))

@wch is there a way to override/replace a theme element on the current plot?

@baptiste
Copy link
Contributor Author

@baptiste baptiste commented Aug 5, 2015

The prior version of themes let you have custom grobs, but no one ever used its not a common request.

Maybe, but another way to look at it is that if it's too difficult/hacky, no-one will think it's possible in the first place. I posted about ~10 answers over the years on the mailing list and SO, with the old and new theme systems; most of them would otherwise be unanswered, or involve heavy post-processing.
Other examples I can remember included replacing the axis labels with small images, chemical formulas, or tables.

But it's just a test for inheritance, so if your custom grob implements the text protocol, why don't you inherit from element_text?

it doesn't work, unfortunately, for reasons I don't understand. I've updated the SO code by-the-way, as it wasn't working anymore.

@hadley
Copy link
Member

@hadley hadley commented Aug 6, 2015

@baptiste I provided an example that works for me

@baptiste
Copy link
Contributor Author

@baptiste baptiste commented Aug 29, 2015

it works, but the %+replace% workaround is still not very intuitive, is there a way to get + theme(strip.text.x = element_custom()) to work?

Here's a practical example: http://stackoverflow.com/a/32281523/471093

@lock lock bot locked as resolved and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants