diff --git a/.travis.yml b/.travis.yml index e55fb0c5..009c43a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,9 @@ addons: sudo: false +os: + - linux + apt_packages: - r-cran-rjava diff --git a/R/DESCRIPTION b/R/DESCRIPTION index 80854abc..092006de 100755 --- a/R/DESCRIPTION +++ b/R/DESCRIPTION @@ -1,8 +1,8 @@ Package: loon Type: Package Title: Interactive Statistical Data Visualization -Version: 1.3.3 -Date: 2021-02-24 +Version: 1.3.4 +Date: 2021-03-15 Authors@R: c(person(given = "Adrian", family = "Waddell", email = "adrian@waddell.ch", role = c("aut")), diff --git a/R/NEWS.md b/R/NEWS.md index a53aee5f..701b6644 100755 --- a/R/NEWS.md +++ b/R/NEWS.md @@ -1,3 +1,52 @@ +# loon 1.3.4 + +* A new vignette + + - "Logical queries in interactive graphics" + + Explains how to use loon's interactive plots and inspector to construct logical + queries on the displayed data. + + An *enriched* version of `mtcars` is used for illustration. + + How a plot's `linkingKey` (from Loon's linking model) can be used to access the correct + elements of any logical operation is also described. + +* minor bug fixes and improvements + + - Three minor bug fixes on **facets** + + - If the `by` is a formula with `loon` n-dimensional states, no need to provide additional data, + the formula should be able to be converted to a data frame given by the states info. + + - When `by` has missing values, it is treated as other n-dimensional states: + + drop NAs, leave warnings (which one are removed) + + - Removed unnecessary warnings. + + - `l_pairs()` has a progress bar for constructing, linking, and connecting the scales of the plots. + + there is now a new argument `showProgressBar` that allows this to be suppressed (e.g. in RMarkdown files) + + - for histograms of factors and character vectors: default setting of arg `showFactors` + + - previously: `TRUE` whenever number of factor levels (or equivalent unique strings) < 10 + - now: `TRUE` whenever < 25 to accomodate common factors like `month` or the 24 hours in a day. + + - updated documentation on `l_layer()` + + +* testing + + - As all examples are wrapped in `if(interactive)`, check all interactive examples to ensure they work well + + - hexadecimal colours seem to get slightly (generally ignorable) different hexadecimal values for colours in `tcltk` on Solaris (see 1.3.3 comments). this caused problems in testing for exact colours on Solaris. + + Until this is sorted out, the testing for colour hex values in the test suite were commented out to prevent loon from being unnecessarily archived on CRAN. (The colours are correct, but our previous solution generated warnings, which may cause problems for CRAN acceptance.) Likely, in the future, we suppress the warning from `l_hexcolor()` when testing. + + - for iris dataset in tests, we drop an observation so that for each species, the number of observations are different. + # loon 1.3.3 * an extremely minor update diff --git a/R/R/datasets.R b/R/R/datasets.R index 86a9ccc8..31fd148e 100755 --- a/R/R/datasets.R +++ b/R/R/datasets.R @@ -64,7 +64,6 @@ #' Research and Data Analysis (Martens, H., Russwurm, H., eds.), p. 189, #' Applied Science Publ., Barking. #' -#' Wikipedia \url{https://en.wikipedia.org/} #' #' "olive" diff --git a/R/R/graphutils.R b/R/R/graphutils.R index 10c6ee96..9975b6e2 100755 --- a/R/R/graphutils.R +++ b/R/R/graphutils.R @@ -178,10 +178,8 @@ as.graph <- function(loongraph) { #' @export #' #' @examples -#' if (requireNamespace("Rgraphviz", quietly = TRUE)) { #' g <- loongraph(letters[1:4], letters[1:3], letters[2:4], FALSE) -#' plot(g) -#' } +#' plot.loongraph <- function(x, ...) { requireNamespace("Rgraphviz", quietly = TRUE) || stop("Rgraphviz library required") @@ -443,11 +441,8 @@ graphproduct <- function(U,V, type=c("product", "tensor", "strong"), separator=' #' #' LLG <- linegraph(LG) #' -#' graphreduce(LLG) +#' R_LLG <- graphreduce(LLG) #' -#' if (requireNamespace("Rgraphviz", quietly = TRUE)) { -#' plot(graphreduce(LLG)) -#' } #' graphreduce <- function(graph, separator) { diff --git a/R/R/l_layer.R b/R/R/l_layer.R index f9039bc8..b69f97c8 100755 --- a/R/R/l_layer.R +++ b/R/R/l_layer.R @@ -143,7 +143,8 @@ l_layer <- function(widget, x, ...) { #' @seealso \code{\link[stats]{density}} #' @export #' @export l_layer.density -#' @examples { +#' @examples +#' if(interactive()){ #' d <- density(faithful$eruptions, bw = "sj") #' h <- l_hist(x = faithful$eruptions, yshows="density") #' l <- l_layer.density(h, d, color="steelblue", linewidth=3) diff --git a/R/README.md b/R/README.md index 74bb4801..c20cee91 100755 --- a/R/README.md +++ b/R/README.md @@ -1,7 +1,9 @@ ## loon -[![Build Status](https://travis-ci.org/great-northern-diver/loon.svg?branch=master)](https://travis-ci.org/great-northern-diver/loon) [![CRAN\_Status\_Badge](https://www.r-pkg.org/badges/version/loon)](https://cran.r-project.org/package=loon) +[![Build Status](https://travis-ci.org/great-northern-diver/loon.svg?branch=master)](https://travis-ci.org/great-northern-diver/loon) +[![Total downloads](https://cranlogs.r-pkg.org/badges/grand-total/loon?color=blue)](https://cran.r-project.org/package=loon) +[![CRAN\_Status\_Badge](https://www.r-pkg.org/badges/version/loon)](https://cran.r-project.org/package=loon) loon is an extendible interactive data visualization system designed for exploratory visualization. diff --git a/R/_pkgdown.yml b/R/_pkgdown.yml index 31936ca8..90b12a0a 100755 --- a/R/_pkgdown.yml +++ b/R/_pkgdown.yml @@ -13,12 +13,14 @@ navbar: menu: - text: Introduction href: articles/introduction.html + - text: Saving loon plots + href: articles/savingLoonPlots.html + - text: Logical queries in interactive graphics + href: articles/logicalQueries.html - text: Analysis example href: articles/minorities.html - text: Teaching example href: articles/teaching-example-smoothing.html - - text: Saving loon plots - href: articles/savingLoonPlots.html - text: Videos menu: - text: the (not so) humble (interactive) histogram diff --git a/R/cran-comments.md b/R/cran-comments.md index c1447532..9d47ca41 100755 --- a/R/cran-comments.md +++ b/R/cran-comments.md @@ -1,18 +1,72 @@ ## Test evironments -* local OS X, R 3.5.1 -* local Ubuntu 18.04 R 3.5.1 and R-devel (2018-09-29 r75381) -* local Windows 10 R 3.5.1 -* Ubuntu 14.04.5 (on travis-ci) R 3.5.1 and R-devel (2018-09-29 r75381) +* local OSX, Big Sur 11.2.1, R 4.0.2 +* Ubuntu Xenial 16.04 (on travis-ci) +* check_win_devel + - using R Under development (unstable) (2021-03-14 r80087) + - using platform: x86_64-w64-mingw32 (64-bit) + - using session charset: ISO8859-1 + +* Windows Server 2008 R2 SP1, R-devel, 32/64 bit +* Ubuntu Linux 20.04.1 LTS, R-release, GCC +* Fedora Linux, R-devel, clang, gfortran ## R CMD check results -There were no ERRORs or WARNINGs. +0 errors +0 warnings +1 NOTE about maintainer -## Downstream dependencies + ... NOTE + Maintainer: 'R. Wayne Oldford ' + +### Solaris and bioconductor package RgraphViz + +**rhub::check_on_solaris()**: + +1 Error (cannot find/install suggested package `Rgraphviz)` + + - Unable to determine a solution. (have tried adding BiocViews: to DESCRIPTION with no luck) + +- Preparing build, see status at -Sometimes R CMD check fails with the ERROR: + https://builder.r-hub.io/status/loon_1.3.4.tar.gz-a8636ac65fcf46899d204dc1c39bafce -Error in MASS::isoMDS(d = D, k = 5) : object 'VR_mds_init_data' not found +... -This error seems to disappear when I re-install MASS with `install.packages('MASS')`. + E checking package dependencies (3.5s) + Package suggested but not available: ‘Rgraphviz’ + + The suggested packages are required for a complete check. + Checking can be attempted without them by setting the environment + variable _R_CHECK_FORCE_SUGGESTS_ to a false value. + + See section ‘The DESCRIPTION file’ in the ‘Writing R Extensions’ + manual. + + +**Relevant Snippet from Rhub**: + +- Installing package dependencies\ + +- Running R CMD check + + setting _R_CHECK_FORCE_SUGGESTS_ to false + + setting R_COMPILE_AND_INSTALL_PACKAGES to never + + setting _R_CHECK_THINGS_IN_CHECK_DIR_ to false + + setting R_REMOTES_STANDALONE to true + + setting R_REMOTES_NO_ERRORS_FROM_WARNINGS to true + + setting _R_CHECK_FORCE_SUGGESTS_ to true + + setting _R_CHECK_CRAN_INCOMING_USE_ASPELL_ to true + +- using log directory 'C:/Users/USERzVBgqDuhyS/loon.Rcheck' +- using R Under development (unstable) (2021-02-15 r80013) +- using platform: x86_64-w64-mingw32 (64-bit) + +## Downstream dependencies diff --git a/R/inst/images/Apulia.png b/R/inst/images/Apulia.png deleted file mode 100755 index 20716487..00000000 Binary files a/R/inst/images/Apulia.png and /dev/null differ diff --git a/R/inst/images/Calabria.png b/R/inst/images/Calabria.png deleted file mode 100755 index c6a3aaf2..00000000 Binary files a/R/inst/images/Calabria.png and /dev/null differ diff --git a/R/inst/images/Liguria.png b/R/inst/images/Liguria.png deleted file mode 100755 index 36618224..00000000 Binary files a/R/inst/images/Liguria.png and /dev/null differ diff --git a/R/inst/images/Sardinia.png b/R/inst/images/Sardinia.png deleted file mode 100755 index fe4a917e..00000000 Binary files a/R/inst/images/Sardinia.png and /dev/null differ diff --git a/R/inst/images/Sicily.png b/R/inst/images/Sicily.png deleted file mode 100755 index 3f7f23f6..00000000 Binary files a/R/inst/images/Sicily.png and /dev/null differ diff --git a/R/inst/images/Umbria.png b/R/inst/images/Umbria.png deleted file mode 100755 index b140cd17..00000000 Binary files a/R/inst/images/Umbria.png and /dev/null differ diff --git a/R/man/figures/gestures_move.png b/R/man/figures/gestures_move.png old mode 100755 new mode 100644 index cd86ffe2..e2eb768e Binary files a/R/man/figures/gestures_move.png and b/R/man/figures/gestures_move.png differ diff --git a/R/man/figures/gestures_rotate.png b/R/man/figures/gestures_rotate.png old mode 100755 new mode 100644 index 5623541e..93c2f594 Binary files a/R/man/figures/gestures_rotate.png and b/R/man/figures/gestures_rotate.png differ diff --git a/R/man/figures/gestures_select.png b/R/man/figures/gestures_select.png old mode 100755 new mode 100644 index 31c839c2..d1a927de Binary files a/R/man/figures/gestures_select.png and b/R/man/figures/gestures_select.png differ diff --git a/R/man/figures/gestures_zoom_pan.png b/R/man/figures/gestures_zoom_pan.png old mode 100755 new mode 100644 index 5ef245f4..d7eef8ea Binary files a/R/man/figures/gestures_zoom_pan.png and b/R/man/figures/gestures_zoom_pan.png differ diff --git a/R/man/graphreduce.Rd b/R/man/graphreduce.Rd index f6667c60..62389e7e 100755 --- a/R/man/graphreduce.Rd +++ b/R/man/graphreduce.Rd @@ -27,10 +27,7 @@ LG <- linegraph(G) LLG <- linegraph(LG) -graphreduce(LLG) +R_LLG <- graphreduce(LLG) -if (requireNamespace("Rgraphviz", quietly = TRUE)) { - plot(graphreduce(LLG)) -} } diff --git a/R/man/l_layer.density.Rd b/R/man/l_layer.density.Rd index 745d4d22..cd8d2f0a 100755 --- a/R/man/l_layer.density.Rd +++ b/R/man/l_layer.density.Rd @@ -21,7 +21,7 @@ layer object handle, layer id Layer a line that represents a kernel density estimate. } \examples{ -{ +if(interactive()){ d <- density(faithful$eruptions, bw = "sj") h <- l_hist(x = faithful$eruptions, yshows="density") l <- l_layer.density(h, d, color="steelblue", linewidth=3) diff --git a/R/man/l_plot.Rd b/R/man/l_plot.Rd old mode 100755 new mode 100644 diff --git a/R/man/l_plot3D.Rd b/R/man/l_plot3D.Rd old mode 100755 new mode 100644 diff --git a/R/man/l_plot_ts.Rd b/R/man/l_plot_ts.Rd old mode 100755 new mode 100644 diff --git a/R/man/olive.Rd b/R/man/olive.Rd index 341a43fc..bf904295 100755 --- a/R/man/olive.Rd +++ b/R/man/olive.Rd @@ -49,8 +49,6 @@ Forina, M., Armanino, C., Lanteri, S., and Tiscornia, E. (1983) "Classification of Olive Oils from their Fatty Acid Composition", in Food Research and Data Analysis (Martens, H., Russwurm, H., eds.), p. 189, Applied Science Publ., Barking. - - Wikipedia \url{https://en.wikipedia.org/} } \seealso{ \code{\link{oliveLocations}} diff --git a/R/man/plot.loongraph.Rd b/R/man/plot.loongraph.Rd index 3d732c71..b594e860 100755 --- a/R/man/plot.loongraph.Rd +++ b/R/man/plot.loongraph.Rd @@ -16,8 +16,6 @@ This function converts the loongraph object to one of class graph and the plots it with its respective plot method. } \examples{ -if (requireNamespace("Rgraphviz", quietly = TRUE)) { g <- loongraph(letters[1:4], letters[1:3], letters[2:4], FALSE) - plot(g) -} + } diff --git a/R/vignettes/SavingLoonPlots.Rmd b/R/vignettes/SavingLoonPlots.Rmd index 24ac56fa..3ee6b076 100644 --- a/R/vignettes/SavingLoonPlots.Rmd +++ b/R/vignettes/SavingLoonPlots.Rmd @@ -29,15 +29,8 @@ library(loon.data) library(loon) library(gridExtra) -imageDirectory <- "./images/savingLoonPlots" -dataDirectory <- "./data/savingLoonPlots" -path_concat <- function(path1, ..., sep="/") { - # The "/" is standard unix directory separator and so will - # work on Macs and Linux. - # In windows the separator might have to be sep = "\" or - # even sep = "\\" or possibly something else. - paste(path1, ..., sep = sep) - } +imageDirectory <- file.path(".", "images", "savingLoonPlots") +dataDirectory <- file.path(".", "data", "savingLoonPlots") ``` --- @@ -201,12 +194,12 @@ knitr::include_graphics("myplot_via_R.png") ```{r load the saved plots, echo = FALSE, eval=FALSE} # The one exported from RStudio -knitr::include_graphics(path_concat(imageDirectory, "myplot_via_RStudio.png")) +knitr::include_graphics(file.path(imageDirectory, "myplot_via_RStudio.png")) # Followed by the one saved using l_export # (note that background grid is missing) -knitr::include_graphics(path_concat(imageDirectory, "myplot_via_l_export.pdf")) +knitr::include_graphics(file.path(imageDirectory, "myplot_via_l_export.pdf")) # And finally, the one saved using R's png device -knitr::include_graphics(path_concat(imageDirectory, "myplot_via_R.png")) +knitr::include_graphics(file.path(imageDirectory, "myplot_via_R.png")) ``` Alternatively, you could use **LaTeX** if you want more control. For example, the following @@ -274,7 +267,7 @@ p_savedStates <- l_getSavedStates(file = "p_savedStates") ``` ```{r get p states back, echo = FALSE} -p_savedStates <- l_getSavedStates(file = path_concat(dataDirectory, "p_savedStates")) +p_savedStates <- l_getSavedStates(file = file.path(dataDirectory, "p_savedStates")) ``` A new plot is constructed and the saved states transferred to it. @@ -330,7 +323,7 @@ Now all of the states are available when this file is read back in. p_focusOnVersicolor <- l_getSavedStates(file = "p_focusOnVersicolor") ``` ```{r, echo = FALSE} -p_focusOnVersicolor <- l_getSavedStates(file = path_concat(dataDirectory, "p_focusOnVersicolor")) +p_focusOnVersicolor <- l_getSavedStates(file = file.path(dataDirectory, "p_focusOnVersicolor")) ``` When it comes to transferring the states to a new plot there are many choices. We could go with a large collection of display states (more than the default states but still excluding more "basic" states about panning and zooming for example). To see which states, we add the argument `returnNames = TRUE`: diff --git a/R/vignettes/images/intro/panning.png b/R/vignettes/images/intro/panning.png old mode 100755 new mode 100644 index cff49d32..29f3e16f Binary files a/R/vignettes/images/intro/panning.png and b/R/vignettes/images/intro/panning.png differ diff --git a/R/vignettes/images/intro/selecting.png b/R/vignettes/images/intro/selecting.png old mode 100755 new mode 100644 index 8a5c64ba..1cefcd40 Binary files a/R/vignettes/images/intro/selecting.png and b/R/vignettes/images/intro/selecting.png differ diff --git a/R/vignettes/images/intro/zooming.png b/R/vignettes/images/intro/zooming.png old mode 100755 new mode 100644 index b7a5d725..79ed9ded Binary files a/R/vignettes/images/intro/zooming.png and b/R/vignettes/images/intro/zooming.png differ diff --git a/R/vignettes/introduction.Rmd b/R/vignettes/introduction.Rmd index 14cbc59a..b7c49f14 100755 --- a/R/vignettes/introduction.Rmd +++ b/R/vignettes/introduction.Rmd @@ -20,9 +20,8 @@ knitr::opts_chunk$set( set.seed(12314159) -imageDirectory <- "./images/intro" -dataDirectory <- "data" -path_concat <- function(path1, path2, sep="/") {paste(path1, path2, sep = sep)} +imageDirectory <- file.path(".", "images", "intro") +# dataDirectory <- file.path(".", "data", "intro") ``` > "Exposure, the effective laying open of the data to display the unanticipated, @@ -73,13 +72,13 @@ two windows to appear. One is the scatterplot: ```{r loonQuakeOriginal, out.width= "60%", fig.align="center", echo=FALSE} -knitr::include_graphics(path_concat(imageDirectory, "quakesOriginal.png")) +knitr::include_graphics(file.path(imageDirectory, "quakesOriginal.png")) ``` and the other a "loon inspector": ```{r looninspectorQuakeOriginal, out.width= "30%", fig.align="center", echo=FALSE} -knitr::include_graphics(path_concat(imageDirectory, "inspectorQuakesOriginal.png")) +knitr::include_graphics(file.path(imageDirectory, "inspectorQuakesOriginal.png")) ``` @@ -106,7 +105,7 @@ To pan the plot, select the plot interior with the right (or secondary) mouse bu \vspace{-0.05\textheight} ```{r panning, out.width= "40%", fig.align="center", echo=FALSE} -knitr::include_graphics(path_concat(imageDirectory, "panning.png")) +knitr::include_graphics(file.path(imageDirectory, "panning.png")) ``` Try it. Select anywhere on the scatterplot and move it @@ -130,7 +129,7 @@ Another way to dynamically focus on different parts of the plot is by zooming, u \vspace{-0.05\textheight} ```{r zooming, out.width= "40%", fig.align="center", echo=FALSE} -knitr::include_graphics(path_concat(imageDirectory, "zooming.png")) +knitr::include_graphics(file.path(imageDirectory, "zooming.png")) ``` To try it, note that there is a small cluster of 16 points towards the top left of the scatterplot. @@ -157,7 +156,7 @@ Using zooming and panning on the "World View" There are two ways to directly select points on the scatterplot using the mouse: either by selection (one at a time or multiple selections) or by "sweep selection" as shown below: ```{r point selection, out.width= "40%", fig.align="center", echo=FALSE} -knitr::include_graphics(path_concat(imageDirectory, "selecting.png")) +knitr::include_graphics(file.path(imageDirectory, "selecting.png")) ``` To try this out, on the scatterplot (which should contain only 16 points) @@ -254,7 +253,7 @@ You should now have four different coloured groups or clusters. When done, turn the selection back to the defaults: ```{r select defaults, out.width= "40%", fig.align="left", echo=FALSE} -knitr::include_graphics(path_concat(imageDirectory, "inspectorSelectDefaults.png")) +knitr::include_graphics(file.path(imageDirectory, "inspectorSelectDefaults.png")) ``` That is, @@ -305,7 +304,7 @@ For example: ### adding colours to the inspector ```{r looninspector plus 10 cols, out.width= "30%", fig.align="center", echo=FALSE} -knitr::include_graphics(path_concat(imageDirectory, "inspectorQuakesPlus10Cols.png")) +knitr::include_graphics(file.path(imageDirectory, "inspectorQuakesPlus10Cols.png")) ``` More colours can be added directly by clicking on the `+` or the `+5` in the colour modification section of the inspector. @@ -755,11 +754,11 @@ Try this out. ```{r quakesGuidesMapInspector, out.width= "30%", fig.align="center", echo=FALSE} -knitr::include_graphics(path_concat(imageDirectory, "quakesGuidesMapInspector.png")) +knitr::include_graphics(file.path(imageDirectory, "quakesGuidesMapInspector.png")) ``` ```{r quakesGuidesMap, out.width= "50%", fig.align="center", echo=FALSE} -knitr::include_graphics(path_concat(imageDirectory, "quakesGuidesMap.png")) +knitr::include_graphics(file.path(imageDirectory, "quakesGuidesMap.png")) ``` As can be seen in the world view, much of the map is outside of the plot display (shown as the black-bordered rectangle in the world view). @@ -776,7 +775,7 @@ Adding the map allows us to see the effect of all three plot scaling choices ava The effect is best seen on the world view: ```{r worldViewScaling, out.width= "90%", fig.align="center", echo=FALSE} -knitr::include_graphics(path_concat(imageDirectory, "quakesWorldViewScaling.png")) +knitr::include_graphics(file.path(imageDirectory, "quakesWorldViewScaling.png")) ``` Note that the plot in the world view matches that of the actual plot. Also the aspect ratio changes with the scaling. @@ -789,7 +788,7 @@ Note that the plot in the world view matches that of the actual plot. Also the The map is added as a layer, which can be seen by selecting the "Layers" tab in the inspector: ```{r quakesLayersInspector, out.width= "70%", fig.align="center", echo=FALSE} -knitr::include_graphics(path_concat(imageDirectory, "quakesLayersInspector.png")) +knitr::include_graphics(file.path(imageDirectory, "quakesLayersInspector.png")) ``` This allows a lot of interaction with the layers - for example changing their display order, making some of them invisible, grouping layers, and so on. @@ -957,7 +956,7 @@ Note that selection effectively shows the relations in one plot **conditional** Observations in a `loon` plot are uniquely identified (for the purpose of linking) by their `linkingKey`. Pardon the pun but this is the key to linking in `loon`. For the most part, the default linking is all that you ever need do. -Trouble may arise, however, if you want to link two different plots that were created with different data frames whose rows so not match row for row. For example, one `data.frame` might be a re-ordering of the rows of the other. Or, it might be a subset of the rows of the other. +Trouble may arise, however, if you want to link two different plots that were created with different data frames whose rows do not match row for row. For example, one `data.frame` might be a re-ordering of the rows of the other. Or, it might be a subset of the rows of the other. In either case, to have linking work properly the `linkingKey` of the plots associated with the two data frames need to be managed. diff --git a/R/vignettes/logicalQueries.Rmd b/R/vignettes/logicalQueries.Rmd new file mode 100755 index 00000000..33e40069 --- /dev/null +++ b/R/vignettes/logicalQueries.Rmd @@ -0,0 +1,318 @@ +--- +title: "Logical queries in interactive graphics" +author: "R.W. Oldford" +date: "`r Sys.Date()`" +output: + html_vignette: + toc: true +vignette: > + %\VignetteIndexEntry{Logical queries} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} + +--- + +```{r setup, include=FALSE} +knitr::opts_chunk$set( + echo = TRUE, + tidy.opts = list(width.cutoff = 65), + tidy = FALSE) + +set.seed(12314159) + +imageDirectory <- "./images/logic" +dataDirectory <- "data" +``` + +One of the principal strengths of linked plots is the ease with which one can form complex logical queries on the data. + +```{r library_loon, eval = FALSE, echo = TRUE, fig.align="center", fig.width = 6, fig.height = 4, out.width = "75%", warning=FALSE, message=FALSE} +library(loon) +``` + +## The cars of the 1974 Motor Trends magazine + +Begin with a classic data set in `R` -- `mtcars`. +For the sake of illustration, some enrichment of the variables and their values will be made: + +```{r new variates} +data(mtcars, package = "datasets") + +mtcars$country <- c("Japan", "Japan", "Japan", "USA", "USA", "USA", "USA", + "Germany", "Germany", "Germany", "Germany", "Germany", + "Germany", "Germany", "USA", "USA", "USA", "Italy", + "Japan", "Japan", "Japan", "USA", "USA", "USA", "USA", + "Italy", "Germany", "UK", "USA", "Italy", "italy", "Sweden") +mtcars$continent <- c("Asia", "Asia", "Asia", "North America", "North America", + "North America", "North America", "Europe", "Europe", + "Europe", "Europe", "Europe", "Europe", "Europe", + "North America", "North America", "North America", + "Europe", "Asia", "Asia", "Asia", "North America", + "North America", "North America", "North America", + "Europe", "Europe", "Europe", "North America", + "Europe", "Europe", "Europe" ) +mtcars$company <- c("Mazda", "Mazda", "Nissan", "AMC", "AMC", "Chrysler", + "Chrysler", "Mercedes", "Mercedes", "Mercedes", "Mercedes", + "Mercedes", "Mercedes", "Mercedes", "GM", "Ford", + "Chrysler", "Fiat", "Honda", "Toyota", "Toyota", "Chrysler", + "AMC", "GM", "GM", "Fiat", "Porsche", "Lotus", "Ford", + "Ferrari", "Maserati", "Volvo") + +mtcars$Engine <- factor(c("V-shaped", "Straight")[mtcars$vs +1], + levels = c("V-shaped", "Straight")) +mtcars$Transmission <- factor(c("automatic", "manual")[mtcars$am +1], + levels = c("automatic", "manual")) + +mtcars$vs <- NULL # These are redundant now +mtcars$am <- NULL # +``` + +For this illustration, it will be convenient to separate categorical from continuous data. + +```{r define variable types} +varTypes <- split(names(mtcars), + sapply(mtcars, + FUN = function(x){ + if(is.factor(x)|is.character(x)){ + "categorical" + } else {"numeric"} } )) +``` + +`varTypes` is a list with two named components: `categorical` and `numeric`. + +## Some interactive plots + +To explore the data, several interactive plots will likely have been constructed. +Typically, these will have been constructed one at a time and assigned to the same linking group (perhaps via the inspector). + +Below, histograms/barplots are constructed for each categorical variable and assigned to that variable name now prefixed by `h_` for "histogram". + +```{r histograms of categorical variates, eval = FALSE} +for (varName in varTypes$categorical) { + assign(paste0("h_", varName), + l_hist(mtcars[ , varName], showFactors = TRUE, + xlabel = varName, title = varName, + linkingGroup = "Motor Trend")) +} +``` + +These are not evaluated in this vignette. Note that all are in the same `linkingGroup`. + +Other linked plots might exist as well -- for example, a scatterplot of `gear` (the number of forward gears) versus `disp` (the engine displacement in cubic inches). + +```{r, eval = FALSE} +p <- with(mtcars, l_plot(disp, cyl, + xlabel = "engine displacement", ylabel = "number of cylinders", + title = "1974 Motor Trend cars", + linkingGroup = "Motor Trend", + size = 10, showScales = TRUE, + itemLabel = rownames(mtcars), showItemLabels = TRUE + )) +``` + +Note that +- each car's name appears as the `itemLabel` for that point in the plot (to be revealed as a "tooltip" style pop up), and that +- the plot `p` is in the same linking group as the histograms. + +Through a combination of selection, inversion, deactivation, and reactivation, logical queries may be made interactively on the data. + +For simplicity, the basic logical operators are illustrated below using only the histograms. +More generally, these apply to any interactive `loon` graphic. + + + +## Interactive logical operations + +Five logical conditions/operations illustrated here are the basic ones: + +1. `A` is `TRUE` +2. Negation: (NOT `A`) is `TRUE` +3. Inclusive OR: (`A` OR `B`) is `TRUE` (one or the other or both), +4. Conjunction: (`A` AND `B`) are both `TRUE` +5. Exclusive OR: (`A` XOR `B`) meaning (`A` is `TRUE`) or (`B` is `TRUE`) but (`A` AND `B`) is FALSE + + +Each of these corresponds to a sequence of actions on the plots and/or inspector. +Whatever is highlighted in the end corresponds to the result. + +Again, for simplicity all operations are illustrated by interacting with values of categorical variates in the various histograms. +Any of the logical elements could also have been that satisfying numerical constraints by undertaking the corresponding actions on a scatterplot (or histogram of continuous values). + +Each logical operator is illustrated in turn: + +1. `A` ($= A$) + + *on the plot* select `A`, + + - e.g., click on `"manual"` bar from the `Transmission` histogram + + - highlighted $\iff$ `Transmission == "manual"` is `TRUE` + + +2. **NOT** `A` ($= \overline{A}~~$ or $~~\neg A$) + + *on a plot* select `A`, + + *from the inspector* click `invert` + + - e.g., click on `"North America"` bar from the `continent` histogram, + + then invert + + - highlighted $\iff$ `continent == "North America"` is `FALSE` + + - all that is highlighted is **not** `"North America"`, namely `"Asia"` or `"Europe"` + +3. `A` **OR** `B` ($= A \cup B~~$ or $~~A \lor B$), + + *on a plot* select `A`, + + *on the same (or a different but linked) plot* ``- select `B` + + - e.g., click on `"manual"` bar from `Transmission` histogram, + + then while holding down the `` key, + + click on the `Mercedes` bar in the `company` histogram + + + - highlighted $\iff$ `Transmission == "manual"` is `TRUE` + **OR** `company = "Mercedes"` is `TRUE` (or both) + + +4. `A` **AND** `B` ($= A \cap B$ or $A \land B$) + + lots of solutions, here is one that always works + + *on a plot* select `A`, + + *from the inspector*, `invert` then `deactivate` (only `A` remains), + + *from a plot of the remaining* select `B`, + + *from the inspector* `reactivate` all + + - elements are highlighted $\iff A \cap B$ + + - e.g. try highlighting all European cars with manual transmissions. + + + +5. `A` **XOR** `B` ($= (A \cup B) \cap (\overline{A \cap B})$ or $(A \lor B) \land \neg({A \land B})$) + + *following steps in 4*, select `A` **AND** `B`, + + *from the inspector* `invert` then `deactivate` (only $\neg({A \land B})$ remains) + + *following steps in 3*, select `A` **OR** `B`, + + *from the inspector* `reactivate` (only `A` **XOR** `B` is highlighted) + + +Other logical conditions (including numerical ones such as `disp > 300` on the scatterplot `p`) are constructed as a combination of the above (as in exclusive or). + +These can be quite complex and it may help, after some number of steps, to mark intermediary results by colour (or also glyph in scatterplots). + +**Note** that because of possibly missing data, not all linked plots may share the same set of observations. + +## Missing data and linking keys + +The `mtcars` data is an example of a complete data set. +Had there been missing values, then these would not appear in loon plots that require them. + +For example, suppose `data` has four variables `A`, `B`, `C`, and `D`, and +```{r, eval = FALSE} +data <- data.frame(A = sample(c(rnorm(10), NA), 10, replace = FALSE), + B = sample(c(rnorm(10), NA), 10, replace = FALSE), + C = sample(c("firebrick", "steelblue", NA), 10, replace = TRUE), + D = sample(c(1:10, NA), 10, replace = FALSE)) +p_test <- l_plot(x = data$A, y = data$B, color = data$C, linkingGroup = "test missing") +h_test <- l_hist(x = data$D, color = data$C, linkingGroup = "test missing") +``` + +Then + +- wherever an `NA` appears in any of `A`, `B`, or `C`, that point will be missing from `p_test` + + Note that it is generally *not a good idea* to use `C` for any simple display characteristic like `color` if indeed `C` has missing values since this will remove non-missing `x` and `y` values from the plot. Not all values of `x` and `y` would then be accessible from the plot for logical queries, + + +- wherever an `NA` appears in either of `C` or `D`, that point will be missing from `h_test` + +Using logical operations on the original `data` to change plot properties (e.g. select values) can be challenging when data values are missing in the plot (since what is missing depends on what was missing at the time of its construction). + +For example, +```{r, eval = FALSE} +p_test["selected"] <- (data$A > 0) +``` +**may not work**! + +- The logical operation on the data (`data$A > 0`) will typically be longer than the corresponding x value `p_test["x"]` in the plot and so will not work. + +- Even if the logical vector is of the right length (and contains no `NA`s itself), the values may not correctly match the data points. + +There are **two general approaches** to logical queries when `data` contains `NA`s. + +1. Using **complete data** + + If, like `mtcars`, the data being used contains no `NA`s then conducting logical queries on the plot will be identical to conducting them on the data. + + If the data is not complete (contains one or more `NA`), it can be made complete by removing all observations (rows) that contain an `NA`. E.g. replacing `data` by `c_data <- na.omit(data)`. + + - any logic on `c_data` will match that on plots made from `c_data`. + + - depending on the amount and pattern of missing data, *this could critically reduce the amount of data in the analysis*. + +2. Using **the information in the loon plots**. Of course, this is the **recommended** approach when data is missing. + + Logical queries can then be made + + a. **directly on the plots**, either + + - interactively as described in the previous sections, or, + - programmatically as in `p_test["x"] > 0` in place of `data$A > 0`. + + or + + b. **directly on the data and applied to the plots** + + To help manage this, the `linkingKey` *of each plot* can be used. + + - the default value for each plot is a character vector with entries + + from `"0"` to `"n-1"` where `n = `nrow(data)`. + + These are easily turned into the row numbers for the original data. + + E.g. in `p_test` the row numbers of `data` that correspond to the points is + + `1 + as.numeric(p_test["linkingKey"])` + + Logical values for the rows of `data` can then select points in `p` as follows + + ```{r, eval = FALSE} + LogVal <- data$A > data$B + p["selected"] <- logVal[1 + as.numeric(p_test["linkingKey"])] + ``` + + Similarly for `h_test`. E.g., compare `p_test["linkingKey"]` and `h_test["linkingKey]"`. + + - **Note**: the user can always provide their own character vector `linkingKey` for their plots. + + - E.g., `linkingKey = rownames(data)` + + If so, then more care may be needed to use these to identify rows in a logical vector. + +### loon's linking model + +Loon's linking model has the following three parts + +- a `linkingGroup` which identifies which plots are linked +- a `linkingKey`, a character vector where each element is a key uniquely identifying a single observation in the plot (no two observations in the same plot can have the same value in the linking key), and +- the *linked display states* each plot has declared (e.g. see `l_getlinkedStates()`). + +Observations in different plots (in the same linking group) are linked (in that their linked states change together) if and only if they have the same linking key. + +Points appearing in different plots (in the same `linkingGroup`) which matched on the value of their `linkingKey` will share the same value for their linked states. + + diff --git a/R/vignettes/teaching-example-smoothing.Rmd b/R/vignettes/teaching-example-smoothing.Rmd index dc92105a..f29a4fad 100755 --- a/R/vignettes/teaching-example-smoothing.Rmd +++ b/R/vignettes/teaching-example-smoothing.Rmd @@ -27,16 +27,8 @@ set.seed(12314159) library(loon.data) library(loon) library(knitr) - -imageDirectory <- "./images/teaching-example-smoothing" -dataDirectory <- "./data/teaching-example-smoothing" -path_concat <- function(path1, ..., sep="/") { - # The "/" is standard unix directory separator and so will - # work on Macs and Linux. - # In windows the separator might have to be sep = "\" or - # even sep = "\\" or possibly something else. - paste(path1, ..., sep = sep) - } +imageDirectory <- file.path(".", "images", "teaching-example-smoothing") +dataDirectory <- file.path(".", "data", "teaching-example-smoothing") ``` diff --git a/Readme.md b/Readme.md index 6d8a3513..249bfc01 100755 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,7 @@ # loon [![Build Status](https://travis-ci.org/great-northern-diver/loon.svg?branch=master)](https://travis-ci.org/great-northern-diver/loon) [![CRAN\_Status\_Badge](http://www.r-pkg.org/badges/version/loon)](https://cran.r-project.org/package=loon) +[![Total downloads](https://cranlogs.r-pkg.org/badges/grand-total/loon?color=blue)](https://cran.r-project.org/package=loon) [![](https://cranlogs.r-pkg.org/badges/loon)](https://cran.r-project.org/package=loon) `loon` is a toolkit for interactive data visualization and diff --git a/copyTcl2Python.sh b/copyTcl2Python.sh index f2fc58f7..ff5142cc 100755 --- a/copyTcl2Python.sh +++ b/copyTcl2Python.sh @@ -1,11 +1,11 @@ #!/bin/sh -if [ -d "Python/diver/Tcl/images"]; then +if [ -d "Python/diver/Tcl/images" ]; then echo "Delete Python Tcl images folder" rm -R Python/diver/Tcl/images fi -if [ -d "Python/diver/Tcl/library"]; then +if [ -d "Python/diver/Tcl/library" ]; then echo "Delete Python Tcl library folder" rm -R Python/diver/Tcl/library fi diff --git a/copyTcl2R.sh b/copyTcl2R.sh index 62d08fed..7d5ab46b 100755 --- a/copyTcl2R.sh +++ b/copyTcl2R.sh @@ -1,6 +1,6 @@ #!/bin/sh -if [ -d "R/inst"]; then +if [ -d "R/inst" ]; then echo "Delete inst folder" rm -R R/inst fi diff --git a/docs/404.html b/docs/404.html index 4ae24ad9..26ef0005 100755 --- a/docs/404.html +++ b/docs/404.html @@ -79,7 +79,7 @@ loon - 1.3.3 + 1.3.4 @@ -102,13 +102,16 @@ Introduction
  • - Analysis example + Saving loon plots
  • - Teaching example + Logical queries in interactive graphics
  • - Saving loon plots + Analysis example +
  • +
  • + Teaching example
  • @@ -131,7 +134,7 @@ @@ -131,7 +134,7 @@ @@ -90,7 +93,7 @@ @@ -90,7 +93,7 @@ @@ -90,7 +93,7 @@ @@ -131,7 +134,7 @@ @@ -90,7 +93,7 @@ @@ -131,7 +134,7 @@ -
  • introduced the method plot.loon() so that plot(p) of a loon plot p will now draw the corresponding grid object on the current device
  • +
  • introduced the method plot.loon() so that plot(p) of a loon plot p will now draw the corresponding grid object on the current device
  • @@ -472,7 +532,7 @@

    Contents

    -

    Site built with pkgdown 1.6.1.

    +

    Site built with pkgdown 1.5.1.

    diff --git a/docs/pkgdown.css b/docs/pkgdown.css index 1273238d..c01e5923 100644 --- a/docs/pkgdown.css +++ b/docs/pkgdown.css @@ -244,14 +244,14 @@ nav[data-toggle='toc'] .nav .nav > .active:focus > a { .ref-index th {font-weight: normal;} -.ref-index td {vertical-align: top; min-width: 100px} +.ref-index td {vertical-align: top;} .ref-index .icon {width: 40px;} .ref-index .alias {width: 40%;} .ref-index-icons .alias {width: calc(40% - 40px);} .ref-index .title {width: 60%;} .ref-arguments th {text-align: right; padding-right: 10px;} -.ref-arguments th, .ref-arguments td {vertical-align: top; min-width: 100px} +.ref-arguments th, .ref-arguments td {vertical-align: top;} .ref-arguments .name {width: 20%;} .ref-arguments .desc {width: 80%;} diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml index a601b65e..7c3e2f54 100755 --- a/docs/pkgdown.yml +++ b/docs/pkgdown.yml @@ -1,9 +1,10 @@ pandoc: 2.7.3 -pkgdown: 1.6.1 +pkgdown: 1.5.1 pkgdown_sha: ~ articles: introduction: introduction.html - SavingLoonPlots: SavingLoonPlots.html + logicalQueries: logicalQueries.html + savingLoonPlots: savingLoonPlots.html teaching-example-smoothing: teaching-example-smoothing.html -last_built: 2021-03-10T21:31Z +last_built: 2021-03-16T17:38Z diff --git a/docs/reference/L2_distance.html b/docs/reference/L2_distance.html index cf3bea77..2b3dc2cf 100755 --- a/docs/reference/L2_distance.html +++ b/docs/reference/L2_distance.html @@ -84,7 +84,7 @@ loon - 1.3.3 + 1.3.4 @@ -107,13 +107,16 @@ Introduction
  • - Analysis example + Saving loon plots
  • - Teaching example + Logical queries in interactive graphics
  • - Saving loon plots + Analysis example +
  • +
  • + Teaching example
  • @@ -136,7 +139,7 @@