-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Allow passing a function as data #1486
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
Conversation
This will make it possible to pass a function as the data argument that will modify the global data for the layer. It is indeed an esoteric use case, but for ggplot2 extension developers it is the only way to intercept the global data prior to passing it through the relevant Stat object. Furthermore the change is really minor and cheap. If you dislike the approach please consider another way for extension builders to modify the data prior to Stat...
Have just found a problem with the use of facets. Will ned to make some changes |
Resolve data upon extraction within ggplot_build
update from master
It has been fixed now. The function is now applied during ggplot_build as part of data extraction from the layers |
|
||
if (!is.function(data)) { | ||
data <- fortify(data) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just add fortify.function <- function(x, data) x
?
@hadley The documentation stated that fortify might become deprecated in the future, so I chose to just ignore that approach. If fortify will remain I can definitely work around by creating fortify methods... |
@@ -22,7 +22,13 @@ ggplot_build <- function(plot) { | |||
} | |||
|
|||
layers <- plot$layers | |||
layer_data <- lapply(layers, function(y) y$data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't the right place either - if you wanted to preserve this basic approach it would be better to add a get_data()
method (probably needs a better name) to the layer object.
Fortify is here for now, so you should use it. If it changes in the future, the unit tests should pick it up. On that note, you also need some unit tests ;) |
I'll use fortify then. Ignore this PR. Ah, yes - the unit tests. They will happen eventually, but I needed to make sure that I had the general structure in place. Also, they tend to make me loose interest in a project due to their dreadful nature :-) Having published mainly through Bioconductor I've been forced to use it though (which is definitely a good thing) |
... And ggraph is a week old so I think I'm entitled to doing the fun stuff for now :-) |
Reopening. fortify is called in There will need to be some changes somewhere in ggplot2 for this to work. Should I redo the PR in the style of a get_data method to Layer as you proposed? |
Yeah - I'd recommend a new PR with:
|
Having slept on it I have some reservations with the approach (no - not the unit tests:-). But it is ultimately up to you. The promise of I kind feel that passing a function is a beefed up version of passing I would personally find it most clear if Again - it is ultimately up to you. Just some concerns over the clarity of the implementation. |
I don't feel that strongly about the fortify issue. I do think it makes sense to have a function that returns the data from the layer, however it is stored (either directly, as a waiver, or via a function) - and |
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/ |
This PR will make it possible to supply a function as the data argument to the layer function. The function will be applied to the global data of the plot and the result will be used in the layer.
The change is proposed to give extension developers just a tad more power when building custom features. Currently (to my knowledge) data can only be intercepted by a compute_* in a stat, and modifications have already been applied at this point.
My personal need for this feature is that I'm developing a ggplot2 extension library for dealing with graph/network data, and this type of data is not really fitting for a single data.frame as normally accepted in ggplot2. My current solution (which involves this PR) is to convert the graph into two data.frames: one describing the nodes and one describing the edges. The edge data.frame will be added as an attribute to the node data.frame. On calls to edge specific geoms the layer will get a function extracting the edges, passed as the data argument ensuring that it is the edge data that is being made available to the stats and geoms.
The changes are quite minor and does not change ggplot2 behaviour unless a function is passed to the layer. In that case the call to fortify is pushed down from layer() to map_layout() where the function is called on the global data (plot_data).