-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
element_text size using vector #3492
Comments
Would you mind turning this into a reprex (short for minimal reproducible example)? It's especially helpful for ggplot2, since it automatically generates and uploads the plots (or lack thereof), which makes it much easier to go through at a glance. If you've never heard of a reprex before, you might want to start by reading the tidyverse.org help page. Right now the best way to install reprex is: # install.packages("devtools")
devtools::install_github("tidyverse/reprex") If you run into problems with access to your clipboard, you can specify an outfile for the reprex, and then copy and paste (or drag and drop) the contents here. reprex::reprex(input = "fruits_stringdist.R", outfile = "fruits_stringdist.md") Thanks |
Thank you for the hint with the clipboard library(tidyverse)
library(tibble)
ds <- mtcars %>%
rownames_to_column() %>%
select(car = rowname, mpg)
ds_size = rep(8, nrow(ds))
ds_size[10] <- 12
ds %>%
ggplot(aes(x = car, y = mpg)) +
coord_flip() +
theme(axis.text.y = element_text(size = ds_size)) Created on 2019-08-19 by the reprex package (v0.3.0) |
Hmm, I get the same results you've shown above with the dev version. Here it is with ggplot2 3.0.0 library(tidyverse)
ds <- mtcars %>%
rownames_to_column() %>%
select(car = rowname, mpg)
ds_size = rep(8, nrow(ds))
ds_size[10] <- 12
ds %>%
ggplot(aes(x = car, y = mpg)) +
coord_flip() +
theme(axis.text.y = element_text(size = ds_size)) And below is with 3.1.1 library(tidyverse)
ds <- mtcars %>%
rownames_to_column() %>%
select(car = rowname, mpg)
ds_size = rep(8, nrow(ds))
ds_size[10] <- 12
ds %>%
ggplot(aes(x = car, y = mpg)) +
coord_flip() +
theme(axis.text.y = element_text(size = ds_size)) Created on 2019-08-19 by the reprex package (v0.3.0) |
It seems the element takes the sum of the values as margin. BTW, is library(ggplot2)
d <- data.frame(x = letters[1:10], y = 1:10, stringsAsFactors = FALSE)
f <- function(n) {
ggplot(d) +
geom_point(aes(x, y)) +
theme(axis.text.x = element_text(size = rep(8, n)))
}
f(1) f(10) f(100) Created on 2019-08-19 by the reprex package (v0.3.0) |
@batpigandme Sorry, I forgot the geometry in my reprex. Here is a new one library(ggplot2)
ds <- data.frame(
car = rownames(mtcars),
mpg = mtcars$mpg
)
ds_size = rep(8, nrow(ds))
ds_size[10] <- 12
ggplot(ds, ggplot2::aes(x = car, y = mpg)) +
geom_col() +
coord_flip() +
theme(axis.text.y = element_text(size = ds_size)) Created on 2019-08-19 by the reprex package (v0.3.0) @yutannihilation I cannot remember where I got the hint, but using a vector for face still works library(ggplot2)
ds <- data.frame(
car = rownames(mtcars),
mpg = mtcars$mpg
)
ds_face = rep("plain", nrow(ds))
ds_face[10] <- "bold"
ggplot(ds, ggplot2::aes(x = car, y = mpg)) +
geom_col() +
coord_flip() +
theme(axis.text.y = element_text(face = ds_face)) Created on 2019-08-19 by the reprex package (v0.3.0) Thank you |
Yeah, it works and probably should, but I feet the individual specifications should belong to the scale, not to the theme. @clauswilke |
I'm not a big fan of setting text parameters as vectors in this way, mostly because it's unpredictable when it works and when it doesn't. It works for axes but it doesn't work for legends, for internal technical reasons that are not visible to the enduser. Having said that, I don't understand why this specific example fails. We should track down the cause, because it suggests something weird is going on with the |
Thanks, agreed. Let's see what's happening here. |
Here is what I think is happening. (I don't quite understand yet why it only happens for font size, and not for font face, so maybe I'm wrong.) This line returns now a vector of descent values rather than just one value: Line 69 in 1ae034e
ggplot2:::font_descent("", "plain", rep(10, 5), 1)
#> [1] 0.0292290581597222inches 0.0292290581597222inches
#> [3] 0.0292290581597222inches 0.0292290581597222inches
#> [5] 0.0292290581597222inches Created on 2019-08-19 by the reprex package (v0.3.0) This vector results in vectors Lines 197 to 205 in 1ae034e
And the Lines 115 to 121 in 1ae034e
Again, this doesn't yet fully explain what exactly is happening, but I think it's on the right track. Importantly, it's based on a line that was changed with the latest release: The previous function |
Thanks. For facet strips, it seems we do the right thing to pass a single Lines 608 to 631 in b842024
edit: But, facet strips doesn't accept variable sizes... library(ggplot2)
d <- data.frame(x = letters[1:10], y = 1:10, stringsAsFactors = FALSE)
ggplot(d) +
geom_point(aes(x, y)) +
facet_wrap(vars(x)) +
theme(strip.text = element_text(size = 1:10 * 5)) Created on 2019-08-20 by the reprex package (v0.3.0) |
I made a PR that seems to fix the problem, though I still don't fully understand how exactly things go wrong. #3493 |
Confirmed #3493 fixes the issue. But, I too don't understand how the things are supposed to work here... Is ggplot2:::font_descent("", "plain", 10, 1)
#> [1] 0.03125inches
ggplot2:::font_descent("", "plain", c(10, 10), 1)
#> [1] 0.03125inches 0.03125inches
ggplot2:::font_descent("", "plain", c(10, 20), 1)
#> [1] 0.03125inches 0.03125inches
ggplot2:::font_descent("", "plain", 1:10 * 10, 1)
#> [1] 0.03125inches 0.03125inches 0.03125inches 0.03125inches 0.03125inches
#> [6] 0.03125inches 0.03125inches 0.03125inches 0.03125inches 0.03125inches
# probably the cache works wrong here...
ggplot2:::font_descent("", "plain", 1:10 * 20, 1)
#> [1] 0.03125inches 0.03125inches
#> [3] 0.03125inches 0.03125inches
#> [5] 0.03125inches 0.0520833333333333inches
#> [7] 0.0520833333333333inches 0.0520833333333333inches
#> [9] 0.0520833333333333inches 0.0520833333333333inches Created on 2019-08-20 by the reprex package (v0.3.0) |
Yes, the font cache is not working correctly for vectorized input. It loops over the keys but then uses the same parameters for descent lookup each time: Lines 339 to 355 in b842024
@thomasp85 Do you have any strong opinions on how to fix this? Since |
I made a new PR that simplifies |
(Just a note to self)
This behaviour comes from here; Lines 214 to 216 in b842024
|
But why do we see the behavior only for font size but not for example for font face? I still don't get that. |
Curiously, it seems another bug... Here, Line 69 in b842024
e.g. library(ggplot2)
d <- data.frame(x = letters[1:10], y = 1:10, stringsAsFactors = FALSE)
ggplot(d) +
geom_point(aes(x, y)) +
theme(axis.text.x = element_text(size = 30, face = rep("plain", 10))) ggplot(d) +
geom_point(aes(x, y)) +
theme(axis.text.x = element_text(size = 30, family = rep("", 10))) Created on 2019-08-20 by the reprex package (v0.3.0) |
It seems grid::gpar(
fontsize = NULL,
col = NULL,
fontfamily = NULL,
fontface = NULL,
lineheight = NULL
)
#> $fontface
#> NULL Created on 2019-08-20 by the reprex package (v0.3.0) As Lines 209 to 219 in b842024
|
Ok, I see it now. The strange handling of |
I have tested the different parameters for |
Opps, thanks... @clauswilke Lines 74 to 75 in b842024
|
Ok. I think we should just ignore all but the first angle. I expect using multiple angles along the axis never worked (but I've never tried it). |
Agreed.
I confirmed it didn't work at the time of v3.1.1. |
A bit late to this. I honestly think we shouldn’t allow vectorised input in |
There are valid obscure reason for the weirdness of the |
Do you remember how many revdep packages were broken when you tried to stop support vectorised input? #3237 |
Sounds like it was just a single package but I honestly can’t remember. I’d propose that we catch this at the |
OK, if it's just one or two packages, I agree with the idea of warning. It sounds the right approach. |
Let's not say "never". My library(ggplot2)
library(ggtext)
d <- data.frame(x = letters[1:16], y = 1:16, stringsAsFactors = FALSE)
ggplot(d) +
geom_point(aes(x, y)) +
theme(axis.text.x = element_markdown(size = 3*c(5:12, 11:4))) Created on 2019-08-24 by the reprex package (v0.3.0) Also, I feel that the whole I'll add a warning at the drawing stage, so we get a warning exactly where the code receives input it can't handle. This way, if at some point in the future we have more general support for vectorized input, the warning will simply disappear. |
I can only agree with you on On a deeper level, I really don’t like that the theming can become tightly coupled with the exact plot, eg your example will only work with plots that have 16 x-axis labels. I don’t think that should be allowed |
I think @thomasp85’s reasoning is compelling: a theme should not be tied to a specific plot, and any use of vectors should be considered an unsupported hack. That said, I think people we be unhappy if we remove this without warning so I think it’ll have to go through a deprecation cycle. |
I agree we should deprecate it carefully, but we should at the least not build out support for the hack🙂 |
FWIW, I think most of the use cases for this hack can be solved properly using |
I've updated my PR. How is this? library(ggplot2)
d <- data.frame(x = letters[1:16], y = 1:16, stringsAsFactors = FALSE)
ggplot(d) +
geom_point(aes(x, y)) +
theme(axis.text.x = element_text(size = 3*c(5:12, 11:4)))
#> Warning: Vectorized input to `element_text()` is not officially supported.
#> Results may be unexpected or may change in future versions of ggplot2. Created on 2019-08-25 by the reprex package (v0.3.0) |
If we agree to put the vectorized behavior into the deprecation cycle, I think we should choose a bit stronger words to discourage the usage. |
(Just a side comment)
I too felt so, but, after some thinking, now I'm not sure if I can fully agree with this. Leaving the technical details aside, a theme can be tightly coupled with the exact plot; For example, it depends on the length of labels how much angle we should rotate the labels. Using the analogy of HTML and CSS, they are designed to separate theming from the data, but, in practice, elaborated CSSs are so tightly coupled with the exact HTMLs that they cannot be reused easily. |
I don’t think your example is exactly fitting. What I’m talking about is a deep “technical” coupling — not an aesthetic one. True, label rotation may only look good with packed labels, but there are no technical requirements of the plot that means that a plot will fail to render with certain rotation settings. |
Ah, I see. |
* make font_descent() not vectorized. closes #3492. * work around vectorized angles * Add warning when element_text() is used with vectorized input. * add news item
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/ |
Hi,
When using a vector for axis text size in a flipped bar chart, the bars seems to be moved far outside the plot region, and also the text is shifted. I am using ggplot2 version 3.2.1.
I was able to produce the wished plot with ggplot2 version 3.1.1
Thank you
The text was updated successfully, but these errors were encountered: