vegawidget / altair Goto Github PK
View Code? Open in Web Editor NEWR interface to 'Altair'
Home Page: https://vegawidget.github.io/altair
License: Other
R interface to 'Altair'
Home Page: https://vegawidget.github.io/altair
License: Other
How do we go about doing this, particularly when we are testing against our ability to construct Python objects?
As well, how do we go about installing Python and Altair on Travis?
Another question where, hopefully, we can follow keras.
The current strategy seems to be "get it written and committed - we will sort it out later".
This is a reminder to get it sorted-out, when later arrives.
I think there is an opportunity to provide some helper functions. I think we could use some purrr magic to provide functions like:
remove_data()
, which would go through a chart and, well, remove the data.distill_data()
, which would go through a compound chart, see if there are repeated data, and if so remove them in favor of a data
at the "top" of the object.As of now, a chart will render in a browser, but not in the RStudio IDE.
@AliciaSchep notes that she found it necessary to include ES6 promise and symbol polyfills.
Another addition from vega 2.1.0 that might be worth incorporating into documentation is 'add_selection'. It is a method to do the same as chart.properties(selection = single)
. The selection section of the Altair documentation have been updated to make use of that method
Following this comment in #33.
It could be interesting to use listviewer as a tool for examining a chart object.
Could be useful for examples, idea from @heike
This exists in pkgdown for reference examples, but not (yet) for article examples.
TODO:
try pkgdown/extra.js
, based on pkgdown code
raise issue with pkgdown to make "permanent"
This builds on this comment in #33
As a part of this issue, build a new internal function check_altair_versions()
that will evaluate two "version" strings according to this comment, i.e.
# we can test this function
check_altair_versions <- function(version_installed, version_supported) {
# do stuff here
}
iris
- as is - fails.
Just to note for now.
especially the classes used for the methods
Leaving as NULL
can result in a plot with height of about 1100 pixels, most of which is blank.
Workaround for now is to specify height = 400
.
Some discussion follows this suggestion from @AliciaSchep to split off the rendering functions into their own package.
I think this is a good idea, and wish to use this issue as a way to think through potential problems.
I will summarize some of the ideas from the "old" thread here.
In the future, we will be able to use:
library("altair")
alt$datasets$cars()
When the future happens, we will have to update our docs.
The "old" way to make tooltips is broken.
This means:
Change quiet to true for startup.
I like the idea outlined in the 'manifesto' section of having a pipe-able api. However, I imagine doing that manually would be really tedious and brittle -- if the vegalite/altair api changed, requires continual maintenance (what has been an issue for vegalite R package).
If a pipe-able api could be either fully or at least partially created programatically from the python api (e.g. each class turn into a constructor, each class method into an S3 method) that could potentially make it much less tedious.
I think I'll try exploring this a bit and see if it seems work-able at all (right now just a half-baked idea).
As discussed in #24, it would be useful to have ready access to the Vega datasets. As @AliciaSchep shows, reticulate opens a door for us:
data <- reticulate::import("vega_datasets")$data
Another approach is to use that door to build a separate package, a path @haleyjeppson has started down for her own use: haleyjeppson/vegadatasets
Although I like the idea of a package, the problem I see (at least as far as CRAN is concerned) will be to document those datasets.
I wonder if we can use reticulate as a loophole. If we did something like this in zzz.R:
alt <- NULL
vegadata <- NULL
.onLoad <- function(libname, pkgname) {
alt <<- reticulate::import("altair", delay_load = TRUE)
vegadata <<- reticulate::import("vega_datasets", delay_load = TRUE)$data
}
Then, "legally" (I think), we would just have to document the vegadata
object (or whatever we call it).
What do you all think? If you like it, any name-suggestions beyond vegadata
? Maybe vega_data
?
Looks like there are breaking changes at vega-tooltip. See vega/vega-tooltip#196
We will likely need to sort out a stable solution before going "public".
The reticulate package offers Python objects as RC objects in R.
Because RC offers mutable objects, I thought that an altair
(R) object might be mutable, but it appears to show more of a copy-on-modify behavior.
I need to make some examples to demonstrate this to myself.
Regardless of it being copy-on-modify or mutable, it would be useful to determine the intent of the Altair (Python) library.
Looking at example plots in the Altair (python) documentation, the links at the bottom are nicely spaced out:
Looking at the similar plot in the altair (r) documentation:
The links are ugly/overlapping
I think some simple css could fix this issue -- happy to put some together (& try to figure out what the frontend for the Altair documentation is using) and make a PR but figured best to raise an issue first & see if there would be support for that!
Branching off #15...
I have reviewed the way altair approaches the development of the python interface and I wanted to share my impressions. This could be useful if this (or other package, like vegalite) would like to implement something similar.
The python package is divide into:
mark_point
, which is not part of the JSON schema"Model:Q"
means).Anyway, I think there would be value of creating classes that were natively created from the JSON schema and could be autovalidated. On top of that, an R-specific set of functions/methods could be created to provide a more "native" R experience, e.g., instead of encoding x = "Cylinder:Q"
it could allow x = Cylinder
with type detection and even allow x = Cylinder / 1000
, like in other packages.
A JSON-schema validation package would also be very useful and could be spun into its own package.
This is no small undertaking, but I just thought I would share what I learned. Feel free to let me know if I got something wrong.
Possible values of stage
are:
"release"
, to install the released version on Conda-Forge"candidate"
, to install a release-candidate using PyPiIn the future:
"github"
, to install from the Altair GitHub repositoryIf the "release" version is newer than the "candidate" version, specifying "candidate"
will generate a message then install the "release" version.
To support this, create some internal functions:
install_altair_release()
install_altair_candidate()
width
and height
According to the vega-embed reference, any options specified here are overwritten by Vega-Lite.
When you create an alt$Chart()
object, it does not appear to set the width and height if you do not specify them. When you send the chart $to_json()
, default values appear (400 * 300, but I need to confirm).
We also have width
and height
in the vegalite()
function, as (standard) htmlwidgets arguments. It may be useful to sort through all of these ways to set width
and height
to see if there is a best practice (or if we can hook one up).
Another issue it that it's possible to create an alt$Chart()
without specifying dimensions, the width
and height
attributes go undefined until the $to_json()
method is called. It will set a default width and height (I just checked):
> tmp <- alt$Chart()
> tmp
Chart({
})
> tmp$to_json(validate = FALSE)
[1] "{\n \"$schema\": \"https://vega.github.io/schema/vega-lite/v2.json\",\n \"config\": {\n \"view\": {\n \"height\": 300,\n \"width\": 400\n }\n }\n}"
We have at least three different places to set dimensions:
vegalite()
, which passes things on to the htmlwidgetvega_embed()
, to set the embed
argument in vegalite()
Among the first three options, we need to sort out an order-of-precedence. Vega-embed already defers to the chart specification (in the context of Vega-Lite).
I think that the order-of-precedence should be:
vegalite()
vega_embed()
However, I also suspect that in practice, the chart is the right place to set the dimensions. I suspect that this will make itself apparent in compound charts.
For vegalite()
, if the height
and width
are not set explicitly, perhaps they could be set by getting them from the chart-spec.
Reading this over, I still don't think I am writing clearly enough.
With reticulate 1.9 (see rstudio/reticulate#299), this seems to be automatic now.
The CRAN version does yet not have the "pop" fix. rstudio/reticulate#244
Unclear to me if this is an issue.
In the JavaScript Binding section of the htmlwidgets reference, it is suggested to return a copy of the object in our factory function. This is done so that users can access the object.
I don't know what this means in vegalite-land, but I think it is useful to keep in mind.
Could be a useful diagnostic
Everybody likes tooltips...
altair-package.R
following http://r-pkgs.had.co.nz/man.html#man-packages
As an informal manner of testing (#10), it might make sense to try to recreate all the example plots in the vega-lite and Altair galleries.
The python vega datasets can be accessed by importing vega_datasets module using reticulate.
Here is an example of the r code for the bubble plot:
data <- reticulate::import("vega_datasets")$data
source = data$cars()
alt$Chart(r_to_py(source))$mark_point()$encode(
x='Horsepower',
y='Miles_per_Gallon',
size='Acceleration'
) %>% vegalite()
Translating all the examples to R might help identify stuff that doesn't quite work as expected, or help confirm that everything does work as expected!
Focus on tooltip article, showing the "new" Altair method.
The Altair library enables chart concatenation through operators.
+
is for layers
|
for horizontal concatenation
&
for vertical concatenation
What do you think about enabling those operators for altair Chart objects in R?
As an example of how this would get implemented:
"|.altair.vegalite.v2.api.Chart" <- function(e1, e2) {
alt$hconcat(e1,e2)
}
That enables:
(plot_mpg | plot_disp) %>% vegalite()
(Using example in interactive vignette)
Might need to figure out whether method should actually be applied to some parent class and not altair.vegalite.v2.api.Chart
How to extend to as an htmlwidget? Look to vegalite for inspiration?
Using https://bl.ocks.org/-/about and gistr, a function that would set up the gist for a block.
create_block <- function(chart, tooltip, ...) {
}
I think we should keep two candidate versions of _travis.yml
: one for released Altair versions, and another for release candidates. Maybe a in top-level folder travis_scripts
that could be added to .Rbuildignore
.
Regardless, need a "new" travis procedure that will install the "released" version of Altair
Reading the reticulate documentation, I see that we should have some sort of mechanism for installing Altair (and Python?).
The keras has a function install_keras()
- I wonder if we could use that as inspiration: a couple of functions such as install_altair()
and has_altair()
.
Following this suggestion from @AliciaSchep, I wonder if we should rename the rendering function vegalite()
to vegawidget()
? Other ideas? Leave it as-is?
@AliciaSchep suggests that this rendering function, and friends, could be split off into its own package vegawidget that would render all manner of Vega and Vega-Lite specifications.
Over in Altair repo the Altair package has been updated to use newer version of js libraries. How does/will this package attempt to stay up-to-date with versions used by Altair?
see https://github.com/vega/vega-embed
It looks like Vega-Lite overrides a bunch of these options, but it may be useful in the interest of completeness.
Interesting options may include the renderer (canvas/svg) and the footer (Export As ..., and so on).
vega.width
and vega.height
update to current version
This is a part of #33, but the ambition its much smaller - just to make sure that we have the "blessed" versions of JS libraries for this current release candidate, and to make sure that those libraries work as we expect.
@AliciaSchep points out that we can use
alt$VEGALITE_VERSION
alt$VEGAEMBED_VERSION
to determine blessed versions. So this seems like a place to start.
As @AliciaSchep suggests, it would be useful to have a guide on style and how to make a contribution, i.e. run pkgdown or not? I'm sure there's some other things we would want to put in this, too.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.