-
Notifications
You must be signed in to change notification settings - Fork 36
new evaluate does remove identical plot more aggressively #243
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
Comments
I'll try to see if this is deliberate from I recognize that keeping identical plots may not be something to do often, but it feels not good that we broke |
This happens to be tricky, and I am now thinking this could have been a bug in old behavior 🤔 Here are the differences from old behavior v0.24.0 and new one Previously length of Lines 30 to 37 in 6cece5f
and if lower or equal then is would not be considered a for how example, this would have been the values > plot_calls(p1)
[1] "C_plot_new" "palette2" "C_plot_window" "C_title" "C_axis" "C_axis" "C_rect"
> plot_calls(p2)
[1] "C_plot_new" "palette2" "C_plot_window" "C_title" "C_axis" "C_axis" "C_rect"
> length(plot_calls(p2))
[1] 7
> length(plot_calls(p1))
[1] 7 They are equal and they would have been considered different plot... Line 44 in e1ece68
Lines 23 to 28 in e1ece68
In the new version, this is different. Now, if the display list is identical, the plot is ignored Lines 14 to 17 in cadec2f
and only if the length of the old display list is less than the length of the new plot display list this is considered different plot Lines 19 to 22 in cadec2f
In the specific example shared hist(cars$speed)
hist(cars$speed, breaks = "Scott") Those are two calls, but they have the same display list, and this gets filtered out now. So I wonder if this was a bug before, or considered a feature. But previously evaluating the same plot twice, would lead to two recorded plot evaluate::evaluate(function() {
plot(cars$speed)
plot(cars$speed)
}) |> str(max.level = 1)
#> List of 4
#> $ :List of 1
#> ..- attr(*, "class")= chr "source"
#> $ :List of 2
#> ..- attr(*, "engineVersion")= int 16
#> ..- attr(*, "pid")= int 64952
#> ..- attr(*, "Rversion")=Classes 'R_system_version', 'package_version', 'numeric_version' hidden list of 1
#> ..- attr(*, "load")= chr(0)
#> ..- attr(*, "attach")= chr(0)
#> ..- attr(*, "class")= chr "recordedplot"
#> $ :List of 1
#> ..- attr(*, "class")= chr "source"
#> $ :List of 2
#> ..- attr(*, "engineVersion")= int 16
#> ..- attr(*, "pid")= int 64952
#> ..- attr(*, "Rversion")=Classes 'R_system_version', 'package_version', 'numeric_version' hidden list of 1
#> ..- attr(*, "load")= chr(0)
#> ..- attr(*, "attach")= chr(0)
#> ..- attr(*, "class")= chr "recordedplot" And now it is not at all evaluate::evaluate(function() {
plot(cars$speed)
plot(cars$speed)
}) |> str(max.level = 1)
#> List of 3
#> $ :List of 1
#> ..- attr(*, "class")= chr "source"
#> $ :List of 2
#> ..- attr(*, "engineVersion")= int 16
#> ..- attr(*, "pid")= int 67968
#> ..- attr(*, "Rversion")=Classes 'R_system_version', 'package_version', 'numeric_version' hidden list of 1
#> ..- attr(*, "load")= chr(0)
#> ..- attr(*, "attach")= chr(0)
#> ..- attr(*, "class")= chr "recordedplot"
#> $ :List of 1
#> ..- attr(*, "class")= chr "source"
#> - attr(*, "class")= chr [1:2] "evaluate_evaluation" "list" We need a way to restore this. Also because for grid graphics it works ok evaluate::evaluate(function() {
library(ggplot2)
ggplot(penguins) + geom_point(aes(bill_len, bill_dep))
ggplot(penguins) + geom_point(aes(bill_len, bill_dep))
}) |> str(max.level = 1)
#> List of 7
#> $ :List of 1
#> ..- attr(*, "class")= chr "source"
#> $ :List of 1
#> ..- attr(*, "class")= chr "source"
#> $ :List of 4
#> ..- attr(*, "class")= chr [1:3] "rlang_warning" "warning" "condition"
#> $ :List of 3
#> ..- attr(*, "engineVersion")= int 16
#> ..- attr(*, "pid")= int 123828
#> ..- attr(*, "Rversion")=Classes 'R_system_version', 'package_version', 'numeric_version' hidden list of 1
#> ..- attr(*, "load")= chr(0)
#> ..- attr(*, "attach")= chr(0)
#> ..- attr(*, "class")= chr "recordedplot"
#> $ :List of 1
#> ..- attr(*, "class")= chr "source"
#> $ :List of 4
#> ..- attr(*, "class")= chr [1:3] "rlang_warning" "warning" "condition"
#> $ :List of 3
#> ..- attr(*, "engineVersion")= int 16
#> ..- attr(*, "pid")= int 123828
#> ..- attr(*, "Rversion")=Classes 'R_system_version', 'package_version', 'numeric_version' hidden list of 1
#> ..- attr(*, "load")= chr(0)
#> ..- attr(*, "attach")= chr(0)
#> ..- attr(*, "class")= chr "recordedplot"
#> - attr(*, "class")= chr [1:2] "evaluate_evaluation" "list" |
I think this pretty clearly implies it's a bug: evaluate::evaluate(function() {
plot(cars$speed)
plot(cars$speed)
}) |
Hmmmm, but how do we distinguish that case from evaluate::evaluate(function() {
plot(cars$speed)
1 + 1
}) i.e. how can we know if it's a new plot if nothing on the graphics device has changed? It's a bit different with grid, because the grobs get unique names: library(ggplot2)
df <- data.frame(x = 1, y = 1)
ev <- evaluate(function() {
ggplot(df) + geom_point(aes(x, y))
ggplot(df) + geom_point(aes(x, y))
})
waldo::compare(ev[[2]], ev[[4]]) |
Weird behavior. More than two plots do not work the same with old evaluate > packageVersion("evaluate")
[1] ‘0.24.0’
> evaluate(function() {
+ plot(cars$speed)
+ plot(cars$speed)
+ }) |> classes()
+ evaluate(function() {
+ plot(cars$speed)
+ plot(cars$speed)
+ plot(cars$speed)
+ }) |> classes()
[1] "source" "recordedplot" "source" "recordedplot"
[1] "source" "recordedplot" "source" "recordedplot" "source" So deeper bug ? Now I am thinking: what are the odds of a user needing two identical plots or more one after the other? |
Yeah, it seems most likely that this is a bug in their code. It's a bit weird that grid and base graphics differ, but that's due to fundamental differences in the way those systems operate (mostly that grid gives every plot element a unique name). |
This was reported in
Previously, with 0.24.0, this would produce two recorded plot
and knitr would be responsible to keep only one or all depending on
fig.keep
optionsHowever, with evaluate 1.0.0, there is now a new logic to detect different plots
So
fig.keep = 'all'
does not have the effect as there is no second plot to keep now.Is this change expected?
Or could it be something to check when this was rewritten ?
evaluate/R/watchout.R
Lines 62 to 69 in 1c4492b
The text was updated successfully, but these errors were encountered: