From dc521f284bc9aacc6d318909faf6763c3c32a8ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 15:41:49 +0200 Subject: [PATCH 01/48] Use Rmarkdown readme with badges --- README.Rmd | 59 ++++++++++++++++++++++++++++++++++++++++++ README.md | 75 ++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 120 insertions(+), 14 deletions(-) create mode 100644 README.Rmd diff --git a/README.Rmd b/README.Rmd new file mode 100644 index 0000000..8f204f0 --- /dev/null +++ b/README.Rmd @@ -0,0 +1,59 @@ +--- +output: github_document +--- + + + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>", + fig.path = "man/figures/README-", + out.width = "100%" +) +``` +# ggnetwork + + +[![Lifecycle: maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://www.tidyverse.org/lifecycle/#maturing) +[![GitHub tag](https://img.shields.io/github/tag/briatte/ggnetwork.svg?label="latest tag")](https://github.com/briatte/ggnetwork) +[![Travis-CI Build Status](https://travis-ci.org/briatte/ggnetwork.svg?branch=master)](https://travis-ci.org/briatte/ggnetwork) +[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/briatte/ggnetwork?branch=master&svg=true)](https://ci.appveyor.com/project/briatte/ggnetwork) +[![Coverage Status (codecov)](https://codecov.io/gh/briatte/ggnetwork/branch/master/graph/badge.svg)](https://codecov.io/gh/briatte/ggnetwork) +[![CRAN_Status_Badge](http://www.r-pkg.org/badges/version-ago/ggnetwork)](https://cran.r-project.org/package=ggnetwork) +[![cran checks_worst](https://cranchecks.info/badges/worst/ggnetwork)](https://cran.r-project.org/web/checks/check_results_ggnetwork.html) +[![CRAN_Download_total](http://cranlogs.r-pkg.org/badges/grand-total/ggnetwork)](https://cran.r-project.org/package=ggnetwork) + + +This package allows to pass network objects to [`ggplot2`](http://ggplot2.org/), along with several geometries to plot their elements. + +## Installation + +You can install the released version of ggnetwork from [CRAN](https://CRAN.R-project.org) with: + +``` r +install.packages("ggnetwork") +``` + +And the development version from [GitHub](https://github.com/) with: + +``` r +# install.packages("remotes") +remotes::install_github("briatte/ggnetwork") +``` + +__IMPORTANT: the `ggnetwork` package depends on `ggplot2` version 2.0.0 or above.__ + +* * * + +__The package vignette__ contains [detailed examples](https://briatte.github.io/ggnetwork/) of how to use its fortify method and each of its geometries. + +__For further examples__ that use `ggnetwork` with other packages to produce animated graphs, see James Curley's slides on “[Interactive and Dynamic Network Visualization in R](http://curleylab.psych.columbia.edu/netviz/).” + +* * * + +__Comments and suggestions__ are very welcome: please file them as [issues](https://github.com/briatte/ggnetwork/issues). + +__See also__ the [geomnet](https://github.com/sctyner/geomnet), [ggnet](https://github.com/briatte/ggnet) and [ggraph](https://github.com/thomasp85/ggraph) packages for related work. + +__Thanks to__ [Michał Bojanowski](https://github.com/mbojan), [Jake Fisher](https://github.com/jcfisher), [Heike Hofmann](https://github.com/heike), [Pedro Jordano](https://github.com/pedroj), [Moritz Marbach](https://github.com/sumtxt), [Tyler Rinker](https://github.com/trinker), Bertrand Sudre, [Samantha C. Tyner](https://github.com/sctyner), and two anonymous _[R Journal](https://journal.r-project.org/)_ reviewers. \ No newline at end of file diff --git a/README.md b/README.md index 2b79784..1f2c409 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,74 @@ -## This package allows to pass network objects to [`ggplot2`](http://ggplot2.org/), along with several geometries to plot their elements. -__Install from CRAN__, or from GitHub with `devtools`: + -```r -# stable +# ggnetwork + + + +[![Lifecycle: +maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://www.tidyverse.org/lifecycle/#maturing) +[![GitHub +tag](https://img.shields.io/github/tag/briatte/ggnetwork.svg?label=%22latest%20tag%22)](https://github.com/briatte/ggnetwork) +[![Travis-CI Build +Status](https://travis-ci.org/briatte/ggnetwork.svg?branch=master)](https://travis-ci.org/briatte/ggnetwork) +[![AppVeyor Build +Status](https://ci.appveyor.com/api/projects/status/github/briatte/ggnetwork?branch=master&svg=true)](https://ci.appveyor.com/project/briatte/ggnetwork) +[![Coverage Status +(codecov)](https://codecov.io/gh/briatte/ggnetwork/branch/master/graph/badge.svg)](https://codecov.io/gh/briatte/ggnetwork) +[![CRAN\_Status\_Badge](http://www.r-pkg.org/badges/version-ago/ggnetwork)](https://cran.r-project.org/package=ggnetwork) +[![cran +checks\_worst](https://cranchecks.info/badges/worst/ggnetwork)](https://cran.r-project.org/web/checks/check_results_ggnetwork.html) +[![CRAN\_Download\_total](http://cranlogs.r-pkg.org/badges/grand-total/ggnetwork)](https://cran.r-project.org/package=ggnetwork) + + +This package allows to pass network objects to +[`ggplot2`](http://ggplot2.org/), along with several geometries to plot +their elements. + +## Installation + +You can install the released version of ggnetwork from +[CRAN](https://CRAN.R-project.org) with: + +``` r install.packages("ggnetwork") +``` + +And the development version from [GitHub](https://github.com/) with: -# dev -devtools::install_github("briatte/ggnetwork") +``` r +# install.packages("remotes") +remotes::install_github("briatte/ggnetwork") ``` -__IMPORTANT: the `ggnetwork` package depends on `ggplot2` version 2.0.0 or above.__ +**IMPORTANT: the `ggnetwork` package depends on `ggplot2` version 2.0.0 +or above.** -* * * +----- -__The package vignette__ contains [detailed examples](https://briatte.github.io/ggnetwork/) of how to use its fortify method and each of its geometries. +**The package vignette** contains [detailed +examples](https://briatte.github.io/ggnetwork/) of how to use its +fortify method and each of its geometries. -__For further examples__ that use `ggnetwork` with other packages to produce animated graphs, see James Curley's slides on “[Interactive and Dynamic Network Visualization in R](http://curleylab.psych.columbia.edu/netviz/).” +**For further examples** that use `ggnetwork` with other packages to +produce animated graphs, see James Curley’s slides on “[Interactive and +Dynamic Network Visualization in +R](http://curleylab.psych.columbia.edu/netviz/).” -* * * +----- -__Comments and suggestions__ are very welcome: please file them as [issues](https://github.com/briatte/ggnetwork/issues). +**Comments and suggestions** are very welcome: please file them as +[issues](https://github.com/briatte/ggnetwork/issues). -__See also__ the [geomnet](https://github.com/sctyner/geomnet), [ggnet](https://github.com/briatte/ggnet) and [ggraph](https://github.com/thomasp85/ggraph) packages for related work. +**See also** the [geomnet](https://github.com/sctyner/geomnet), +[ggnet](https://github.com/briatte/ggnet) and +[ggraph](https://github.com/thomasp85/ggraph) packages for related work. -__Thanks to__ [Michał Bojanowski](https://github.com/mbojan), [Jake Fisher](https://github.com/jcfisher), [Heike Hofmann](https://github.com/heike), [Pedro Jordano](https://github.com/pedroj), [Moritz Marbach](https://github.com/sumtxt), [Tyler Rinker](https://github.com/trinker), Bertrand Sudre, [Samantha C. Tyner](https://github.com/sctyner), and two anonymous _[R Journal](https://journal.r-project.org/)_ reviewers. +**Thanks to** [Michał Bojanowski](https://github.com/mbojan), [Jake +Fisher](https://github.com/jcfisher), [Heike +Hofmann](https://github.com/heike), [Pedro +Jordano](https://github.com/pedroj), [Moritz +Marbach](https://github.com/sumtxt), [Tyler +Rinker](https://github.com/trinker), Bertrand Sudre, [Samantha C. +Tyner](https://github.com/sctyner), and two anonymous *[R +Journal](https://journal.r-project.org/)* reviewers. From 45c73fe0e4b7d828632a04572ebe610422922a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 15:42:01 +0200 Subject: [PATCH 02/48] update roxygen version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 1dae1e2..196a4fb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -19,7 +19,7 @@ URL: https://github.com/briatte/ggnetwork BugReports: https://github.com/briatte/ggnetwork/issues LazyData: true NeedsCompilation: no -RoxygenNote: 6.0.1 +RoxygenNote: 6.1.1 VignetteBuilder: knitr Depends: ggplot2 (>= 2.0.0), From df655355971c7e1f263097c1419f28bbd14c7907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 15:43:20 +0200 Subject: [PATCH 03/48] update ignore files --- .Rbuildignore | 14 ++++++++++++++ .gitignore | 7 ++----- 2 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 .Rbuildignore diff --git a/.Rbuildignore b/.Rbuildignore new file mode 100644 index 0000000..d61b28f --- /dev/null +++ b/.Rbuildignore @@ -0,0 +1,14 @@ +^pkgdown$ +^_pkgdown\.yml$ +^.github$ +^inst/pkgdown$ +^docs$ +^.*\.Rproj$ +^\.Rproj\.user$ +^README\.Rmd$ +^README +^README-.*\.png$ +^\.travis\.yml$ +^appveyor\.yml$ +^codecov\.yml$ +^\.github$ diff --git a/.gitignore b/.gitignore index d86621c..b437030 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ +**.Rproj.user .Rproj.user -.Rhistory -.RData -.Ruserdata -.Rbuildignore -ggnetwork.Rproj +docs \ No newline at end of file From d90eb824f0841dee1e1fa4cbe87fdfe16c842f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 15:43:33 +0200 Subject: [PATCH 04/48] add Rproj file --- ggnetwork.Rproj | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100755 ggnetwork.Rproj diff --git a/ggnetwork.Rproj b/ggnetwork.Rproj new file mode 100755 index 0000000..3cc56ac --- /dev/null +++ b/ggnetwork.Rproj @@ -0,0 +1,23 @@ +Version: 1.0 + +RestoreWorkspace: No +SaveWorkspace: No +AlwaysSaveHistory: No + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RnwWeave: knitr +LaTeX: pdfLaTeX + +StripTrailingWhitespace: Yes +LineEndingConversion: Posix + +BuildType: Package +PackageUseDevtools: Yes +PackageInstallArgs: --no-multiarch --with-keep.source +PackageRoxygenize: rd,collate,namespace,vignette + +QuitChildProcessesOnExit: Yes From 9a7832c78cadc9186af8f0388b84470a4eb0ff71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 15:45:49 +0200 Subject: [PATCH 05/48] add pkgdown config --- _pkgdown.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 _pkgdown.yml diff --git a/_pkgdown.yml b/_pkgdown.yml new file mode 100644 index 0000000..76bd885 --- /dev/null +++ b/_pkgdown.yml @@ -0,0 +1,7 @@ +template: + params: + bootswatch: simplex + +development: + mode: auto + From 394c1b59290beb568906dbb75a79891c68faae66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 15:46:00 +0200 Subject: [PATCH 06/48] add appveyor config --- appveyor.yml | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..96c985e --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,52 @@ +# DO NOT CHANGE the "init" and "install" sections below + +# Download script file from GitHub +init: + ps: | + $ErrorActionPreference = "Stop" + Invoke-WebRequest http://raw.github.com/krlmlr/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1" + Import-Module '..\appveyor-tool.ps1' + +install: + ps: Bootstrap + +cache: + - C:\RLibrary + +# Adapt as necessary starting from here +version: {build}-{branch} + +environment: + global: + USE_RTOOLS: true + _R_CHECK_FORCE_SUGGESTS_: false + BIOC_USE_DEVEL: FALSE + +build_script: + - travis-tool.sh install_deps + +test_script: + - travis-tool.sh run_tests + +on_failure: + - 7z a failure.zip *.Rcheck\* + - appveyor PushArtifact failure.zip + +artifacts: + - path: '*.Rcheck\**\*.log' + name: Logs + + - path: '*.Rcheck\**\*.out' + name: Logs + + - path: '*.Rcheck\**\*.fail' + name: Logs + + - path: '*.Rcheck\**\*.Rout' + name: Logs + + - path: '\*_*.tar.gz' + name: Bits + + - path: '\*_*.zip' + name: Bit From e86f84602b185cde79955418dc75296302da08ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 15:46:15 +0200 Subject: [PATCH 07/48] add codecov config --- codecov.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 codecov.yml diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..69cb760 --- /dev/null +++ b/codecov.yml @@ -0,0 +1 @@ +comment: false From 5596f840ea94dfda6f9feb100f3c7c407ab8ee38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 15:47:49 +0200 Subject: [PATCH 08/48] complete travis config file with pkgdown; other R version and covr --- .travis.yml | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 468cc47..710f270 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,2 +1,44 @@ -language: r +language: R cache: packages +sudo: true + + +env: + global: + - _R_CHECK_FORCE_SUGGESTS_=false + - R_REMOTES_NO_ERRORS_FROM_WARNINGS=true + - _R_CHECK_SYSTEM_CLOCK_=false + +before_install: + - sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable --yes + - sudo apt-get --yes --force-yes update -qq + - sudo apt-get install --yes libudunits2-dev libproj-dev libgeos-dev libgdal-dev + - Rscript -e 'update.packages(ask = FALSE)' + +r_github_packages: + - r-lib/covr + +matrix: + include: + - r: devel + - r: release + after_success: Rscript -e 'covr::coveralls(); covr::codecov()' + before_deploy: Rscript -e 'remotes::install_cran("pkgdown")' + deploy: + provider: script + script: Rscript -e 'pkgdown::deploy_site_github()' + skip_cleanup: true + - r: 3.1 + - r: 3.2 + - r: 3.3 + - r: 3.4 + - r: 3.5 + - r: 3.6 + +after_success: + - Rscript -e 'covr::coveralls(); covr::codecov()' + +notifications: + email: + on_success: change + on_failure: change From 5e3371db9c01b248b6fca7b8675dd67bf0502061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 16:09:18 +0200 Subject: [PATCH 09/48] add contributors from github --- README.Rmd | 35 ++++++++++++++++++++------- README.md | 70 ++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 79 insertions(+), 26 deletions(-) diff --git a/README.Rmd b/README.Rmd index 8f204f0..e42e6cf 100644 --- a/README.Rmd +++ b/README.Rmd @@ -27,7 +27,7 @@ knitr::opts_chunk$set( This package allows to pass network objects to [`ggplot2`](http://ggplot2.org/), along with several geometries to plot their elements. -## Installation +## Get started You can install the released version of ggnetwork from [CRAN](https://CRAN.R-project.org) with: @@ -44,16 +44,35 @@ remotes::install_github("briatte/ggnetwork") __IMPORTANT: the `ggnetwork` package depends on `ggplot2` version 2.0.0 or above.__ -* * * - __The package vignette__ contains [detailed examples](https://briatte.github.io/ggnetwork/) of how to use its fortify method and each of its geometries. -__For further examples__ that use `ggnetwork` with other packages to produce animated graphs, see James Curley's slides on “[Interactive and Dynamic Network Visualization in R](http://curleylab.psych.columbia.edu/netviz/).” +__For further examples__ that use `ggnetwork` with other packages to produce animated graphs, see James Curley's slides on "[Interactive and Dynamic Network Visualization in R](http://curleylab.psych.columbia.edu/netviz/)." + +--- + +## Getting help + +If you encounter a clear bug, please file a minimal reproducible example on [github](https://github.com/briatte/ggnetwork/issues). +For questions and other discussion, please contact the package maintainer. + +## See also -* * * +Related packages: -__Comments and suggestions__ are very welcome: please file them as [issues](https://github.com/briatte/ggnetwork/issues). +* [geomnet](https://github.com/sctyner/geomnet) +* [ggnet](https://github.com/briatte/ggnet) +* [ggraph](https://github.com/thomasp85/ggraph) -__See also__ the [geomnet](https://github.com/sctyner/geomnet), [ggnet](https://github.com/briatte/ggnet) and [ggraph](https://github.com/thomasp85/ggraph) packages for related work. +## Thanks -__Thanks to__ [Michał Bojanowski](https://github.com/mbojan), [Jake Fisher](https://github.com/jcfisher), [Heike Hofmann](https://github.com/heike), [Pedro Jordano](https://github.com/pedroj), [Moritz Marbach](https://github.com/sumtxt), [Tyler Rinker](https://github.com/trinker), Bertrand Sudre, [Samantha C. Tyner](https://github.com/sctyner), and two anonymous _[R Journal](https://journal.r-project.org/)_ reviewers. \ No newline at end of file +```{r, include = FALSE, eval = FALSE} +usethis::use_tidy_thanks() +``` + +Thanks to two anonymous _[R Journal](https://journal.r-project.org/)_ reviewers.contributors, +[@achmurzy](https://github.com/achmurzy), [@andrewd789](https://github.com/andrewd789), [@ArtemSokolov](https://github.com/ArtemSokolov), [@aterhorst](https://github.com/aterhorst), [@briatte](https://github.com/briatte), [@emillykkejensen](https://github.com/emillykkejensen), [@evinhas](https://github.com/evinhas), [@FinScience](https://github.com/FinScience), [@ghost](https://github.com/ghost), [@instantkaffee](https://github.com/instantkaffee), [@jalapic](https://github.com/jalapic), [@jcfisher](https://github.com/jcfisher), [@jfaganUK](https://github.com/jfaganUK), [@kippjohnson](https://github.com/kippjohnson), [@koheiw](https://github.com/koheiw), [@mbojan](https://github.com/mbojan), [@mcanouil](https://github.com/mcanouil), [@mgagliol](https://github.com/mgagliol), [@mhairi](https://github.com/mhairi), [@minimaxir](https://github.com/minimaxir), [@mkarikom](https://github.com/mkarikom), [@nick-youngblut](https://github.com/nick-youngblut), [@SantiFilippo](https://github.com/SantiFilippo), [@sciabolazza](https://github.com/sciabolazza), [@sctyner](https://github.com/sctyner), [@trinker](https://github.com/trinker) and [@zachcp](https://github.com/zachcp) + + +--- +Please note that this project is released with a [Contributor Code of Conduct](.github/CODE_OF_CONDUCT.md). +By participating in this project you agree to abide by its terms. diff --git a/README.md b/README.md index 1f2c409..3c216d6 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ This package allows to pass network objects to [`ggplot2`](http://ggplot2.org/), along with several geometries to plot their elements. -## Installation +## Get started You can install the released version of ggnetwork from [CRAN](https://CRAN.R-project.org) with: @@ -44,8 +44,6 @@ remotes::install_github("briatte/ggnetwork") **IMPORTANT: the `ggnetwork` package depends on `ggplot2` version 2.0.0 or above.** ------ - **The package vignette** contains [detailed examples](https://briatte.github.io/ggnetwork/) of how to use its fortify method and each of its geometries. @@ -57,18 +55,54 @@ R](http://curleylab.psych.columbia.edu/netviz/).” ----- -**Comments and suggestions** are very welcome: please file them as -[issues](https://github.com/briatte/ggnetwork/issues). - -**See also** the [geomnet](https://github.com/sctyner/geomnet), -[ggnet](https://github.com/briatte/ggnet) and -[ggraph](https://github.com/thomasp85/ggraph) packages for related work. - -**Thanks to** [Michał Bojanowski](https://github.com/mbojan), [Jake -Fisher](https://github.com/jcfisher), [Heike -Hofmann](https://github.com/heike), [Pedro -Jordano](https://github.com/pedroj), [Moritz -Marbach](https://github.com/sumtxt), [Tyler -Rinker](https://github.com/trinker), Bertrand Sudre, [Samantha C. -Tyner](https://github.com/sctyner), and two anonymous *[R -Journal](https://journal.r-project.org/)* reviewers. +## Getting help + +If you encounter a clear bug, please file a minimal reproducible example +on [github](https://github.com/briatte/ggnetwork/issues). +For questions and other discussion, please contact the package +maintainer. + +## See also + +Related packages: + + - [geomnet](https://github.com/sctyner/geomnet) + - [ggnet](https://github.com/briatte/ggnet) + - [ggraph](https://github.com/thomasp85/ggraph) + +## Thanks + +Thanks to two anonymous *[R Journal](https://journal.r-project.org/)* +reviewers.contributors, [@achmurzy](https://github.com/achmurzy), +[@andrewd789](https://github.com/andrewd789), +[@ArtemSokolov](https://github.com/ArtemSokolov), +[@aterhorst](https://github.com/aterhorst), +[@briatte](https://github.com/briatte), +[@emillykkejensen](https://github.com/emillykkejensen), +[@evinhas](https://github.com/evinhas), +[@FinScience](https://github.com/FinScience), +[@ghost](https://github.com/ghost), +[@instantkaffee](https://github.com/instantkaffee), +[@jalapic](https://github.com/jalapic), +[@jcfisher](https://github.com/jcfisher), +[@jfaganUK](https://github.com/jfaganUK), +[@kippjohnson](https://github.com/kippjohnson), +[@koheiw](https://github.com/koheiw), +[@mbojan](https://github.com/mbojan), +[@mcanouil](https://github.com/mcanouil), +[@mgagliol](https://github.com/mgagliol), +[@mhairi](https://github.com/mhairi), +[@minimaxir](https://github.com/minimaxir), +[@mkarikom](https://github.com/mkarikom), +[@nick-youngblut](https://github.com/nick-youngblut), +[@SantiFilippo](https://github.com/SantiFilippo), +[@sciabolazza](https://github.com/sciabolazza), +[@sctyner](https://github.com/sctyner), +[@trinker](https://github.com/trinker) and +[@zachcp](https://github.com/zachcp) + +----- + +Please note that this project is released with a [Contributor Code of +Conduct](.github/CODE_OF_CONDUCT.md). +By participating in this project you agree to abide by its terms. From e7331d1e519d25507fe77ba8734475644901caf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 16:09:41 +0200 Subject: [PATCH 10/48] add COC, contributing, issue template and support --- .github/CODE_OF_CONDUCT.md | 25 ++++++++++++++++++++ .github/CONTRIBUTING.md | 48 ++++++++++++++++++++++++++++++++++++++ .github/ISSUE_TEMPLATE.md | 11 +++++++++ .github/SUPPORT.md | 35 +++++++++++++++++++++++++++ 4 files changed, 119 insertions(+) create mode 100644 .github/CODE_OF_CONDUCT.md create mode 100644 .github/CONTRIBUTING.md create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/SUPPORT.md diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..0343527 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,25 @@ +# Contributor Code of Conduct + +As contributors and maintainers of this project, we pledge to respect all people who +contribute through reporting issues, posting feature requests, updating documentation, +submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free experience for +everyone, regardless of level of experience, gender, gender identity and expression, +sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. + +Examples of unacceptable behavior by participants include the use of sexual language or +imagery, derogatory comments or personal attacks, trolling, public or private harassment, +insults, or other unprofessional conduct. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, +commits, code, wiki edits, issues, and other contributions that are not aligned to this +Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed +from the project team. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by +opening an issue or contacting one or more of the project maintainers. + +This Code of Conduct is adapted from the Contributor Covenant +(https://www.contributor-covenant.org), version 1.0.0, available at +https://contributor-covenant.org/version/1/0/0/. diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..6afec4b --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,48 @@ +# Contributing to ggnetwork + +This outlines how to propose a change to ggnetwork. For more detailed +info about contributing to this, and other tidyverse packages, please see the +[**development contributing guide**](https://rstd.io/tidy-contrib). + +### Fixing typos + +Small typos or grammatical errors in documentation may be edited directly using +the GitHub web interface, so long as the changes are made in the _source_ file. + +* YES: you edit a roxygen comment in a `.R` file below `R/`. +* NO: you edit an `.Rd` file below `man/`. + +### Prerequisites + +Before you make a substantial pull request, you should always file an issue and +make sure someone from the team agrees that it’s a problem. If you’ve found a +bug, create an associated issue and illustrate the bug with a minimal +[reprex](https://www.tidyverse.org/help/#reprex). + +### Pull request process + +* We recommend that you create a Git branch for each pull request (PR). +* Look at the Travis and AppVeyor build status before and after making changes. +The `README` should contain badges for any continuous integration services used +by the package. +* New code should follow the tidyverse [style guide](http://style.tidyverse.org). +You can use the [styler](https://CRAN.R-project.org/package=styler) package to +apply these styles, but please don't restyle code that has nothing to do with +your PR. +* We use [roxygen2](https://cran.r-project.org/package=roxygen2), with +[Markdown syntax](https://cran.r-project.org/web/packages/roxygen2/vignettes/markdown.html), +for documentation. +* We use [testthat](https://cran.r-project.org/package=testthat). Contributions +with test cases included are easier to accept. +* For user-facing changes, add a bullet to the top of `NEWS.md` below the +current development version header describing the changes made followed by your +GitHub username, and links to relevant issue(s)/PR(s). + +### Code of Conduct + +Please note that the ggnetwork project is released with a +[Contributor Code of Conduct](CODE_OF_CONDUCT.md). By contributing to this +project you agree to abide by its terms. + +### See tidyverse [development contributing guide](https://rstd.io/tidy-contrib) +for further details. diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..84f5c43 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,11 @@ +Please briefly describe your problem and what output you expect. If you have a question, please don't use this form. Instead, ask on or . + +Please include a minimal reproducible example (AKA a reprex). If you've never heard of a [reprex](https://reprex.tidyverse.org/) before, start by reading . + +--- + +Brief description of the problem + +```r +# insert reprex here +``` diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md new file mode 100644 index 0000000..736a724 --- /dev/null +++ b/.github/SUPPORT.md @@ -0,0 +1,35 @@ +# Getting help with ggnetwork + +Thanks for using ggnetwork. Before filing an issue, there are a few places +to explore and pieces to put together to make the process as smooth as possible. + +Start by making a minimal **repr**oducible **ex**ample using the +[reprex](https://reprex.tidyverse.org/) package. If you haven't heard of or used +reprex before, you're in for a treat! Seriously, reprex will make all of your +R-question-asking endeavors easier (which is a pretty insane ROI for the five to +ten minutes it'll take you to learn what it's all about). For additional reprex +pointers, check out the [Get help!](https://www.tidyverse.org/help/) section of +the tidyverse site. + +Armed with your reprex, the next step is to figure out [where to ask](https://www.tidyverse.org/help/#where-to-ask). + + * If it's a question: start with [community.rstudio.com](https://community.rstudio.com/), + and/or StackOverflow. There are more people there to answer questions. + * If it's a bug: you're in the right place, file an issue. + * If you're not sure: let the community help you figure it out! If your + problem _is_ a bug or a feature request, you can easily return here and + report it. + +Before opening a new issue, be sure to [search issues and pull requests](https://github.com/tidyverse/ggnetwork/issues) to make sure the +bug hasn't been reported and/or already fixed in the development version. By +default, the search will be pre-populated with `is:issue is:open`. You can +[edit the qualifiers](https://help.github.com/articles/searching-issues-and-pull-requests/) +(e.g. `is:pr`, `is:closed`) as needed. For example, you'd simply +remove `is:open` to search _all_ issues in the repo, open or closed. + + +If you _are_ in the right place, and need to file an issue, please review the +["File issues"](https://www.tidyverse.org/contribute/#issues) paragraph from +the tidyverse contributing guidelines. + +Thanks for your help! From fe8d36a9bb3eeae29dd99054c227481aee81fa05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 16:10:38 +0200 Subject: [PATCH 11/48] remove duplicated "vignette" --- inst/doc/ggnetwork.R | 182 ---------------- inst/doc/ggnetwork.Rmd | 359 ------------------------------- inst/doc/ggnetwork.html | 460 ---------------------------------------- 3 files changed, 1001 deletions(-) delete mode 100644 inst/doc/ggnetwork.R delete mode 100644 inst/doc/ggnetwork.Rmd delete mode 100644 inst/doc/ggnetwork.html diff --git a/inst/doc/ggnetwork.R b/inst/doc/ggnetwork.R deleted file mode 100644 index 32f1a37..0000000 --- a/inst/doc/ggnetwork.R +++ /dev/null @@ -1,182 +0,0 @@ -## ---- echo=FALSE, message=FALSE------------------------------------------ -library(ggplot2) -library(ggnetwork) - -## ---- eval=FALSE--------------------------------------------------------- -# install.packages("ggnetwork") - -## ---- eval=FALSE--------------------------------------------------------- -# devtools::install_github("briatte/ggnetwork") - -## ---- eval=FALSE--------------------------------------------------------- -# install.packages("ggplot2") -# library(ggplot2) - -## ---- message=FALSE------------------------------------------------------ -library(network) -library(sna) -n <- network(rgraph(10, tprob = 0.2), directed = FALSE) - -## ------------------------------------------------------------------------ -n %v% "family" <- sample(letters[1:3], 10, replace = TRUE) -n %v% "importance" <- sample(1:3, 10, replace = TRUE) - -## ------------------------------------------------------------------------ -e <- network.edgecount(n) -set.edge.attribute(n, "type", sample(letters[24:26], e, replace = TRUE)) -set.edge.attribute(n, "day", sample(1:3, e, replace = TRUE)) - -## ------------------------------------------------------------------------ -theme_blank - -## ---- eval=FALSE--------------------------------------------------------- -# ggnetwork(n, layout = "fruchtermanreingold", cell.jitter = 0.75) -# ggnetwork(n, layout = "target", niter = 100) - -## ------------------------------------------------------------------------ -head(ggnetwork(n)) - -## ------------------------------------------------------------------------ -tail(ggnetwork(n)) - -## ---- eval=FALSE--------------------------------------------------------- -# ggplot(n) - -## ---- eval=FALSE--------------------------------------------------------- -# ggplot(ggnetwork(n)) - -## ------------------------------------------------------------------------ -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(aes(linetype = type), color = "grey50") + - theme_blank() - -## ------------------------------------------------------------------------ -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(aes(linetype = type), color = "grey50", curvature = 0.1) + - theme_blank() - -## ------------------------------------------------------------------------ -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(aes(linetype = type), color = "grey50") + - geom_nodes(aes(color = family, size = importance)) + - theme_blank() - -## ---- eval=FALSE--------------------------------------------------------- -# ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + -# geom_edges(aes(color = type)) + -# geom_nodes(aes(color = family)) + -# theme_blank() - -## ------------------------------------------------------------------------ -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(color = "black") + - geom_nodes(color = "black", size = 8) + - geom_nodetext(aes(color = family, label = LETTERS[ vertex.names ]), - fontface = "bold") + - theme_blank() - -## ------------------------------------------------------------------------ -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(color = "black") + - geom_nodelabel(aes(color = family, label = LETTERS[ vertex.names ]), - fontface = "bold") + - theme_blank() - -## ------------------------------------------------------------------------ -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(color = "black") + - geom_nodelabel_repel(aes(color = family, label = LETTERS[ vertex.names ]), - fontface = "bold", box.padding = unit(1, "lines")) + - geom_nodes(color = "black", size = 8) + - theme_blank() - -## ------------------------------------------------------------------------ -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(aes(linetype = type), color = "grey75") + - geom_nodes(color = "gold", size = 8) + - geom_nodetext(aes(label = LETTERS[ vertex.names ])) + - geom_edgetext(aes(label = day), color = "white", fill = "grey25") + - theme_minimal() + - theme(axis.text = element_blank(), - axis.title = element_blank(), - panel.background = element_rect(fill = "grey25"), - panel.grid = element_blank()) - -## ------------------------------------------------------------------------ -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(aes(linetype = type), color = "grey75") + - geom_nodes(color = "gold", size = 8) + - geom_nodetext(aes(label = LETTERS[ vertex.names ])) + - geom_edgetext_repel(aes(label = day), color = "white", fill = "grey25", - box.padding = unit(1, "lines")) + - theme_minimal() + - theme(axis.text = element_blank(), - axis.title = element_blank(), - panel.background = element_rect(fill = "grey25"), - panel.grid = element_blank()) - -## ------------------------------------------------------------------------ -data(emon) -emon[[1]] - -## ---- echo=FALSE--------------------------------------------------------- -ggplot(emon[[1]], aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges() + - geom_nodes(color = "tomato", size = 4) + - theme_blank() - -## ------------------------------------------------------------------------ -ggplot(emon[[1]], aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(arrow = arrow(length = unit(6, "pt"), type = "closed")) + - geom_nodes(color = "tomato", size = 4) + - theme_blank() - -## ---- eval=FALSE--------------------------------------------------------- -# ggnetwork(emon[[1]], weights = "Frequency") - -## ------------------------------------------------------------------------ -ggplot(ggnetwork(emon[[1]], arrow.gap = 0.04, by = "Frequency"), - aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(arrow = arrow(length = unit(6, "pt"), type = "closed"), - aes(color = Sponsorship)) + - geom_nodes(aes(color = Sponsorship), size = 4) + - facet_wrap(~ Frequency) + - theme_facet() - -## ------------------------------------------------------------------------ -theme_facet - -## ------------------------------------------------------------------------ -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(aes(linetype = type), color = "grey50") + - geom_nodes(aes(x, y, color = family, size = 1.5 * importance)) + - geom_nodetext(aes(label = LETTERS[ vertex.names ], size = 0.5 * importance)) + - geom_edgetext(aes(label = day), color = "grey25") + - scale_color_brewer(palette = "Set2") + - scale_size_area("importance", breaks = 1:3, max_size = 9) + - theme_blank() - -## ------------------------------------------------------------------------ -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(color = "grey50", alpha = 0.5) + - geom_nodes(aes(x, y, color = family, size = 5.5 * importance), alpha = 0.5) + - geom_nodes(aes(x, y, color = family, size = 1.5 * importance)) + - scale_color_brewer(palette = "Set1") + - guides(size = FALSE) + - theme_blank() - -## ------------------------------------------------------------------------ -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(color = "grey50", alpha = 0.5) + - geom_nodes(aes(x, y, color = family), size = 3) + - geom_nodelabel_repel(aes(label = vertex.names), - box.padding = unit(1, "lines"), - data = function(x) { x[ x$family == "a", ]}) + - scale_color_brewer(palette = "Set1") + - theme_blank() - -## ---- results='asis', echo=FALSE----------------------------------------- -cat("Last printed on ", gsub("\\s+", " ", format(Sys.time(), "%b %e, %Y")), - ", using ggnetwork version ", as.character(packageVersion("ggnetwork")), - ".", sep = "") - diff --git a/inst/doc/ggnetwork.Rmd b/inst/doc/ggnetwork.Rmd deleted file mode 100644 index 0501193..0000000 --- a/inst/doc/ggnetwork.Rmd +++ /dev/null @@ -1,359 +0,0 @@ ---- -title: 'ggnetwork: Network geometries for ggplot2' -author: "François Briatte" -date: "`r Sys.Date()`" -output: - html_document: - highlight: default - toc: yes -vignette: > - %\VignetteIndexEntry{ggnetwork} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -```{r, echo=FALSE, message=FALSE} -library(ggplot2) -library(ggnetwork) -``` - -> The [`ggnetwork`](https://github.com/briatte/ggnetwork) package provides a way to build network plots with [`ggplot2`](http://ggplot2.org/). - -Install the stable version from CRAN: - -```{r, eval=FALSE} -install.packages("ggnetwork") -``` - -Or use `devtools` to install the latest version of the package [from GitHub](https://github.com/briatte/ggnetwork): - -```{r, eval=FALSE} -devtools::install_github("briatte/ggnetwork") -``` - -The package is meant to be used with `ggplot2` version 2.0.0 or above, so make sure that you update your version of `ggplot2` from CRAN before using `ggnetwork`: - -```{r, eval=FALSE} -install.packages("ggplot2") -library(ggplot2) -``` - -`ggnetwork` further requires the `network` and `sna` packages for network manipulation, and will also install the [`ggrepel`](https://github.com/slowkow/ggrepel) package for repulsive label drawing. - -The `ggnetwork` package is very much related to the development of [`geom_net`](https://github.com/sctyner/ggnet) by [Samantha C. Tyner](https://github.com/sctyner) and [Heike Hoffmann](https://github.com/heike). It also shares some similarity to the [`ggnet` and `ggnet2` functions](https://github.com/briatte/ggnet), which are part of the [`GGally`](https://github.com/ggobi/ggally) package by Barret Schloerke and others. Each of these projects are extensions to Hadley Wickham's implementation of Leland Wilkinson's "grammar of graphics" in [ggplot2](http://ggplot2.org/). - -## Minimal example - -Let's define a small random graph to illustrate each component of `ggnetwork`: - -```{r, message=FALSE} -library(network) -library(sna) -n <- network(rgraph(10, tprob = 0.2), directed = FALSE) -``` - -Let's now add categorical and continuous attributes for both edges and vertices. We'll start with nodes, adding a categorical vertex attribute called `"family"`, which is set to either `"a"`, `"b"` or `"c"`, and a continuous vertex attribute called `"importance"`, which is set to either 1, 2 or 3. - -```{r} -n %v% "family" <- sample(letters[1:3], 10, replace = TRUE) -n %v% "importance" <- sample(1:3, 10, replace = TRUE) -``` - -We now add a categorical edge attribute called `"type"`, which is set to either `"x"`, `"y"` or `"z"`, and a continuous vertex attribute called `"day"`, which is set to either 1, 2 or 3. - -```{r} -e <- network.edgecount(n) -set.edge.attribute(n, "type", sample(letters[24:26], e, replace = TRUE)) -set.edge.attribute(n, "day", sample(1:3, e, replace = TRUE)) -``` - -Last, note that `ggnetwork` contains a "blank" plot theme that will avoid plotting axes on the sides of the network. We will use that theme in most of the plots: - -```{r} -theme_blank -``` - -## Main building blocks - -### `ggnetwork` - -The `ggnetwork` package is organised around a ‘workhorse’ function of the same name, which will ‘flatten’ the network object to a data frame that contains the edge list of the network, along with the edge attributes and the vertex attributes of the sender nodes. - -The network object referred to above might be an object of class `network`, or any data structure that can be coerced to it, such as an edge list, an adjacency matrix or an incidence matrix. If the `intergraph` package is installed, then objects of class `igraph` can also be used with the `ggnetwork` package. - -The data frame returned by `ggnetwork` also contains the coordinates needed for node placement as columns `"x"`, `"y"`, `"xend"` and `"yend"`, which as a consequence are "reserved" names in the context of `ggnetwork`. If these names show up in the edge or the vertex attributes, the function will simply fail to work. - -The default node placement algorithm used by `ggnetwork` to produce these coordinates is the Fruchterman-Reingold force-directed layout algorithm. All of the [placement algorithms implemented in the `sna` package](http://www.rdocumentation.org/packages/sna/functions/gplot.layout) are available through `ggnetwork`, which also accepts additional layout parameters: - -```{r, eval=FALSE} -ggnetwork(n, layout = "fruchtermanreingold", cell.jitter = 0.75) -ggnetwork(n, layout = "target", niter = 100) -``` - -The `layout` argument will also accept user-submitted coordinates as a two-column matrix with as many rows as the number of nodes in the network. - -The top of the data frame produced by `ggnetwork` contains self-loops to force every node to be included in the plot. This explains why the rows shown below have the same values in `"x"` and `"xend"` (and in `"y"` and `"yend"`), and only missing values in the columns corresponding to the edge attributes: - -```{r} -head(ggnetwork(n)) -``` - -The next rows of the data frame contain the actual edges: - -```{r} -tail(ggnetwork(n)) -``` - -The data frame returned by `ggnetwork` has (_N_ + _E_) rows, where _N_ is the number of nodes of the network, and _E_ its number of edges. This data format is very likely to include duplicate information about the nodes, which is unavoidable. - -Note that `ggnetwork` does not include any safety mechanism against duplicate column names. As a consequence, if there is both a vertex attribute called `"na"` and an edge attribute called `"na"`, as in the example above, then the vertex attribute will be renamed `"na.x"` and the edge attribute will be renamed `"na.y"`. - -### `fortify.network` and `fortify.igraph` - -The ‘flattening’ process described above is implemented by `ggnetwork` as `fortify` methods that are recognised by `ggplot2`. As a result, `ggplot2` will understand the following syntax as long as `n` is an object of class `network` or of class `igraph`: - -```{r, eval=FALSE} -ggplot(n) -``` - -However, if the object `n` is a matrix or an edge list to be coerced to a network object, you are required to use the `ggnetwork` function to pass the object to `ggplot2`: - -```{r, eval=FALSE} -ggplot(ggnetwork(n)) -``` - -### `geom_edges` - -Let's now draw the network edges using `geom_edges`, which is just a lightly hacked version of `geom_segment`. In the example below, we map the `type` edge attribute to the linetype of the network edges: - -```{r} -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(aes(linetype = type), color = "grey50") + - theme_blank() -``` - -The other aesthetics that we mapped are the basic coordinates of the network plot. These might also be set as part of the call to `geom_segment`, but setting them at the root of the plot avoids having to repeat them in additional geoms. - -Note that `geom_edges` can also produce curved edges by setting its `curvature` argument to any value above `0` (the default): - -```{r} -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(aes(linetype = type), color = "grey50", curvature = 0.1) + - theme_blank() -``` - -### `geom_nodes` - -Let's now draw the nodes using `geom_nodes`, which is just a lightly hacked version of `geom_point`. In the example below, we map the `family` vertex attribute to the color of the nodes, and make the size of these nodes proportional to the `importance` vertx attribute: - -```{r} -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(aes(linetype = type), color = "grey50") + - geom_nodes(aes(color = family, size = importance)) + - theme_blank() -``` - -Because `ggplot2` follows Wilkinson's grammar of graphics, it accepts only one color scale. In the example above, that scale is mapped to a vertex attribute, but it could have also been mapped to an edge attribute. Mapping a color to _both_ a vertex attribute and an edge attribute will create a single color scale that incorrectly merges both attributes into one: - -```{r, eval=FALSE} -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(aes(color = type)) + - geom_nodes(aes(color = family)) + - theme_blank() -``` - -This is a limitation of `ggnetwork` that would require violating some fundamental aspects of the grammar of graphics to be circumvented. - -## More building blocks - -### `geom_nodetext` - -Let's now add node labels. These are simply plotted over the nodes by the `nodetext` geom, which works exactly like `geom_text`. In the example below, we map the `vertex.names` attribute (which contains numbers 1 to 10) to uppercase letters: - -```{r} -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(color = "black") + - geom_nodes(color = "black", size = 8) + - geom_nodetext(aes(color = family, label = LETTERS[ vertex.names ]), - fontface = "bold") + - theme_blank() -``` - -### `geom_nodelabel` - -If you prefer to use the `geom_label` geom recently introduced in `ggplot2`, `ggnetwork` also supports these through the `nodelabel` geom: - -```{r} -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(color = "black") + - geom_nodelabel(aes(color = family, label = LETTERS[ vertex.names ]), - fontface = "bold") + - theme_blank() -``` - -### `geom_nodetext_repel` and `geom_nodelabel_repel` - -`ggnetwork` supports the repulsive label functions introduced by the `ggrepel` package, which allows to label nodes with non-overlapping annotations. Simply add `_repel` to either `geom_nodetext` or `geom_nodelabel` to use that functionality: - -```{r} -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(color = "black") + - geom_nodelabel_repel(aes(color = family, label = LETTERS[ vertex.names ]), - fontface = "bold", box.padding = unit(1, "lines")) + - geom_nodes(color = "black", size = 8) + - theme_blank() -``` - -### `geom_edgetext` and `geom_edgelabel` - -Let's now add edge labels. These are plotted at mid-distance of the nodes that the edges connect by the `edgetext` geom, which works exactly like `geom_label`, except that its default arguments do not draw a border around the labels. Here's an example where we map the `day` edge attribute to edge labels: - -```{r} -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(aes(linetype = type), color = "grey75") + - geom_nodes(color = "gold", size = 8) + - geom_nodetext(aes(label = LETTERS[ vertex.names ])) + - geom_edgetext(aes(label = day), color = "white", fill = "grey25") + - theme_minimal() + - theme(axis.text = element_blank(), - axis.title = element_blank(), - panel.background = element_rect(fill = "grey25"), - panel.grid = element_blank()) -``` - -The `edgelabel` geom is just an alias of the `edgetext` geom. Note that these geoms are unlikely to produce adequate results if the edges produced by `geom_edges` are curved. - -### `geom_edgetext_repel` and `geom_edgelabel_repel` - -As you would do with nodes, simply add `_repel` to either `geom_edgetext` or `geom_edgelabel` to draw repulsive edge labels: - -```{r} -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(aes(linetype = type), color = "grey75") + - geom_nodes(color = "gold", size = 8) + - geom_nodetext(aes(label = LETTERS[ vertex.names ])) + - geom_edgetext_repel(aes(label = day), color = "white", fill = "grey25", - box.padding = unit(1, "lines")) + - theme_minimal() + - theme(axis.text = element_blank(), - axis.title = element_blank(), - panel.background = element_rect(fill = "grey25"), - panel.grid = element_blank()) -``` - -## More plotting parameters - -This section presents some rather experimental features of `ggnetwork`. - -### Edge arrows - -`ggnetwork` uses code by [Heike Hoffmann](https://github.com/heike) to better show arrows in directed graphs. To illustrate this, we will need a directed graph example, so let's use the first of the seven `emon` networks bundled in the `network` package: - -```{r} -data(emon) -emon[[1]] -``` - -If this network is passed to `ggnetwork` without any further plotting parameter, the result will feature "shortened" edges that do not reach their receiver nodes: - -```{r, echo=FALSE} -ggplot(emon[[1]], aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges() + - geom_nodes(color = "tomato", size = 4) + - theme_blank() -``` - -This is because directed networks are expected to be plotted with edge arrows indicating the directedness of each edge. Adding edge arrows with `geom_edges` works through the same call to the `arrow` function that is supported by `geom_segment`: - -```{r} -ggplot(emon[[1]], aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(arrow = arrow(length = unit(6, "pt"), type = "closed")) + - geom_nodes(color = "tomato", size = 4) + - theme_blank() -``` - -The slightly shortened edges avoid overplotting the edge arrows and the nodes. The amount of "edge shortening" can be set through the `arrow.gap` parameter of `ggnetwork`, which defaults to `0` when the network is undirected and `0.025` when it is. This parameter might need adjustment depending on the size of the nodes, and it will probably not manage to avoid any overplotting when the size of the nodes is not constant. - -### Edge weights - -`ggnetwork` can use an edge attribute as edge weights when computing the network layout. The name of that edge attribute should be passed to the `weights` argument for that to happen, as in this example, which will produce different layouts than if `weights` had been left set to `NULL` (the default): - -```{r, eval=FALSE} -ggnetwork(emon[[1]], weights = "Frequency") -``` - -The Kamada-Kawai is one example of a network layout that supports edge weights. The user should refer to the documentation of each network layout to understand which of these can make use of edge weights. - -If `ggnetwork` finds duplicated edges in a network, it will return a warning, as these edges should probably have been converted to single weighted edges for adequate plotting. - -### Node faceting - -In order for `ggnetwork` to operate correctly with faceted plots, the `by` argument, which is `NULL` by default, can be set to the name of an edge attribute. The result will be a longer data frame that can be plotted with either `facet_wrap` or `facet_grid`, as in the example below, where the faceting variable, the `Frequency` edge attribute, has to be specified twice (once to `ggnetwork`, once to `facet_wrap`): - -```{r} -ggplot(ggnetwork(emon[[1]], arrow.gap = 0.04, by = "Frequency"), - aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(arrow = arrow(length = unit(6, "pt"), type = "closed"), - aes(color = Sponsorship)) + - geom_nodes(aes(color = Sponsorship), size = 4) + - facet_wrap(~ Frequency) + - theme_facet() -``` - -The `by` argument is basically an attempt to bring minimal support for temporal networks in `ggnetwork`. It will systematically show all nodes in all plot facets, using the same coordinates in every facet. For more advanced plots of dynamic networks, the user should turn to the [`ndtv`](https://cran.r-project.org/package=ndtv) and [`tsna`](https://cran.r-project.org/package=tsna) packages. - -The example above also shows how to use a vertex attribute as part of the aesthetics of the edges. Given how `ggnetwork` operates, these vertex attributes will always be those of the sender node. - -Last, the example also shows that `ggnetwork` comes with a theme called `theme_facet`. This theme is a variation of the previously mentioned `theme_blank` that preserves its facet boxes: - -```{r} -theme_facet -``` - -## Additional methods - -Since `ggnetwork` works entirely through `ggplot2`, all `ggplot2` methods apply: - -```{r} -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(aes(linetype = type), color = "grey50") + - geom_nodes(aes(x, y, color = family, size = 1.5 * importance)) + - geom_nodetext(aes(label = LETTERS[ vertex.names ], size = 0.5 * importance)) + - geom_edgetext(aes(label = day), color = "grey25") + - scale_color_brewer(palette = "Set2") + - scale_size_area("importance", breaks = 1:3, max_size = 9) + - theme_blank() -``` - -Similarly, it is possible to use any of the geometries more than once per plot: - -```{r} -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(color = "grey50", alpha = 0.5) + - geom_nodes(aes(x, y, color = family, size = 5.5 * importance), alpha = 0.5) + - geom_nodes(aes(x, y, color = family, size = 1.5 * importance)) + - scale_color_brewer(palette = "Set1") + - guides(size = FALSE) + - theme_blank() -``` - -Last, all geoms provided by `ggnetwork` can be subsetted through the `data` argument, just as any `ggplot2` geom, and as in the example below, which draws only a subset of all node labels: - -```{r} -ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + - geom_edges(color = "grey50", alpha = 0.5) + - geom_nodes(aes(x, y, color = family), size = 3) + - geom_nodelabel_repel(aes(label = vertex.names), - box.padding = unit(1, "lines"), - data = function(x) { x[ x$family == "a", ]}) + - scale_color_brewer(palette = "Set1") + - theme_blank() -``` - ---- - -```{r, results='asis', echo=FALSE} -cat("Last printed on ", gsub("\\s+", " ", format(Sys.time(), "%b %e, %Y")), - ", using ggnetwork version ", as.character(packageVersion("ggnetwork")), - ".", sep = "") -``` diff --git a/inst/doc/ggnetwork.html b/inst/doc/ggnetwork.html deleted file mode 100644 index 852b66b..0000000 --- a/inst/doc/ggnetwork.html +++ /dev/null @@ -1,460 +0,0 @@ - - - - - - - - - - - - - - - -ggnetwork: Network geometries for ggplot2 - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - -
-

The ggnetwork package provides a way to build network plots with ggplot2.

-
-

Install the stable version from CRAN:

-
install.packages("ggnetwork")
-

Or use devtools to install the latest version of the package from GitHub:

-
devtools::install_github("briatte/ggnetwork")
-

The package is meant to be used with ggplot2 version 2.0.0 or above, so make sure that you update your version of ggplot2 from CRAN before using ggnetwork:

-
install.packages("ggplot2")
-library(ggplot2)
-

ggnetwork further requires the network and sna packages for network manipulation, and will also install the ggrepel package for repulsive label drawing.

-

The ggnetwork package is very much related to the development of geom_net by Samantha C. Tyner and Heike Hoffmann. It also shares some similarity to the ggnet and ggnet2 functions, which are part of the GGally package by Barret Schloerke and others. Each of these projects are extensions to Hadley Wickham’s implementation of Leland Wilkinson’s “grammar of graphics” in ggplot2.

-
-

Minimal example

-

Let’s define a small random graph to illustrate each component of ggnetwork:

-
library(network)
-library(sna)
-n <- network(rgraph(10, tprob = 0.2), directed = FALSE)
-

Let’s now add categorical and continuous attributes for both edges and vertices. We’ll start with nodes, adding a categorical vertex attribute called "family", which is set to either "a", "b" or "c", and a continuous vertex attribute called "importance", which is set to either 1, 2 or 3.

-
n %v% "family" <- sample(letters[1:3], 10, replace = TRUE)
-n %v% "importance" <- sample(1:3, 10, replace = TRUE)
-

We now add a categorical edge attribute called "type", which is set to either "x", "y" or "z", and a continuous vertex attribute called "day", which is set to either 1, 2 or 3.

-
e <- network.edgecount(n)
-set.edge.attribute(n, "type", sample(letters[24:26], e, replace = TRUE))
-set.edge.attribute(n, "day", sample(1:3, e, replace = TRUE))
-

Last, note that ggnetwork contains a “blank” plot theme that will avoid plotting axes on the sides of the network. We will use that theme in most of the plots:

-
theme_blank
-
## function(base_size = 12, base_family = "", ...) {
-##   ggplot2::theme_bw(base_size = base_size, base_family = base_family) +
-##     ggplot2::theme(
-##       axis.text = ggplot2::element_blank(),
-##       axis.ticks = ggplot2::element_blank(),
-##       axis.title = ggplot2::element_blank(),
-##       legend.key = ggplot2::element_blank(),
-##       panel.background = ggplot2::element_rect(fill = "white", colour = NA),
-##       panel.border = ggplot2::element_blank(),
-##       panel.grid = ggplot2::element_blank(),
-##       ...
-##     )
-## }
-## <environment: namespace:ggnetwork>
-
-
-

Main building blocks

-
-

ggnetwork

-

The ggnetwork package is organised around a ‘workhorse’ function of the same name, which will ‘flatten’ the network object to a data frame that contains the edge list of the network, along with the edge attributes and the vertex attributes of the sender nodes.

-

The network object referred to above might be an object of class network, or any data structure that can be coerced to it, such as an edge list, an adjacency matrix or an incidence matrix. If the intergraph package is installed, then objects of class igraph can also be used with the ggnetwork package.

-

The data frame returned by ggnetwork also contains the coordinates needed for node placement as columns "x", "y", "xend" and "yend", which as a consequence are “reserved” names in the context of ggnetwork. If these names show up in the edge or the vertex attributes, the function will simply fail to work.

-

The default node placement algorithm used by ggnetwork to produce these coordinates is the Fruchterman-Reingold force-directed layout algorithm. All of the placement algorithms implemented in the sna package are available through ggnetwork, which also accepts additional layout parameters:

-
ggnetwork(n, layout = "fruchtermanreingold", cell.jitter = 0.75)
-ggnetwork(n, layout = "target", niter = 100)
-

The layout argument will also accept user-submitted coordinates as a two-column matrix with as many rows as the number of nodes in the network.

-

The top of the data frame produced by ggnetwork contains self-loops to force every node to be included in the plot. This explains why the rows shown below have the same values in "x" and "xend" (and in "y" and "yend"), and only missing values in the columns corresponding to the edge attributes:

-
head(ggnetwork(n))
-
##           x          y family importance  na.x vertex.names      xend
-## 1 0.1830104 0.42047953      c          2 FALSE            1 0.1830104
-## 2 0.4690597 0.00000000      b          2 FALSE            2 0.4690597
-## 3 1.0000000 0.25891124      c          3 FALSE            3 1.0000000
-## 4 0.2814689 1.00000000      c          3 FALSE            4 0.2814689
-## 5 0.0000000 0.50312529      a          2 FALSE            5 0.0000000
-## 6 0.9306397 0.02183163      c          1 FALSE            6 0.9306397
-##         yend day na.y type
-## 1 0.42047953  NA   NA <NA>
-## 2 0.00000000  NA   NA <NA>
-## 3 0.25891124  NA   NA <NA>
-## 4 1.00000000  NA   NA <NA>
-## 5 0.50312529  NA   NA <NA>
-## 6 0.02183163  NA   NA <NA>
-

The next rows of the data frame contain the actual edges:

-
tail(ggnetwork(n))
-
##            x         y family importance  na.x vertex.names      xend
-## 18 0.8748765 0.2445744      a          2 FALSE            5 0.4203488
-## 19 0.8748765 0.2445744      a          2 FALSE            5 0.4989169
-## 20 1.0000000 0.7239847      c          2 FALSE           10 0.8748765
-## 21 1.0000000 0.7239847      c          2 FALSE           10 0.7160749
-## 22 1.0000000 0.7239847      c          2 FALSE           10 0.7091942
-## 23 1.0000000 0.7239847      c          2 FALSE           10 0.4939615
-##         yend day  na.y type
-## 18 0.5530424   2 FALSE    z
-## 19 0.0000000   2 FALSE    y
-## 20 0.2445744   2 FALSE    x
-## 21 0.6762465   3 FALSE    y
-## 22 0.4029760   1 FALSE    z
-## 23 0.8738652   1 FALSE    x
-

The data frame returned by ggnetwork has (N + E) rows, where N is the number of nodes of the network, and E its number of edges. This data format is very likely to include duplicate information about the nodes, which is unavoidable.

-

Note that ggnetwork does not include any safety mechanism against duplicate column names. As a consequence, if there is both a vertex attribute called "na" and an edge attribute called "na", as in the example above, then the vertex attribute will be renamed "na.x" and the edge attribute will be renamed "na.y".

-
-
-

fortify.network and fortify.igraph

-

The ‘flattening’ process described above is implemented by ggnetwork as fortify methods that are recognised by ggplot2. As a result, ggplot2 will understand the following syntax as long as n is an object of class network or of class igraph:

-
ggplot(n)
-

However, if the object n is a matrix or an edge list to be coerced to a network object, you are required to use the ggnetwork function to pass the object to ggplot2:

-
ggplot(ggnetwork(n))
-
-
-

geom_edges

-

Let’s now draw the network edges using geom_edges, which is just a lightly hacked version of geom_segment. In the example below, we map the type edge attribute to the linetype of the network edges:

-
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
-  geom_edges(aes(linetype = type), color = "grey50") +
-  theme_blank()
-

-

The other aesthetics that we mapped are the basic coordinates of the network plot. These might also be set as part of the call to geom_segment, but setting them at the root of the plot avoids having to repeat them in additional geoms.

-

Note that geom_edges can also produce curved edges by setting its curvature argument to any value above 0 (the default):

-
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
-  geom_edges(aes(linetype = type), color = "grey50", curvature = 0.1) +
-  theme_blank()
-

-
-
-

geom_nodes

-

Let’s now draw the nodes using geom_nodes, which is just a lightly hacked version of geom_point. In the example below, we map the family vertex attribute to the color of the nodes, and make the size of these nodes proportional to the importance vertx attribute:

-
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
-  geom_edges(aes(linetype = type), color = "grey50") +
-  geom_nodes(aes(color = family, size = importance)) +
-  theme_blank()
-

-

Because ggplot2 follows Wilkinson’s grammar of graphics, it accepts only one color scale. In the example above, that scale is mapped to a vertex attribute, but it could have also been mapped to an edge attribute. Mapping a color to both a vertex attribute and an edge attribute will create a single color scale that incorrectly merges both attributes into one:

-
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
-  geom_edges(aes(color = type)) +
-  geom_nodes(aes(color = family)) +
-  theme_blank()
-

This is a limitation of ggnetwork that would require violating some fundamental aspects of the grammar of graphics to be circumvented.

-
-
-
-

More building blocks

-
-

geom_nodetext

-

Let’s now add node labels. These are simply plotted over the nodes by the nodetext geom, which works exactly like geom_text. In the example below, we map the vertex.names attribute (which contains numbers 1 to 10) to uppercase letters:

-
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
-  geom_edges(color = "black") +
-  geom_nodes(color = "black", size = 8) +
-  geom_nodetext(aes(color = family, label = LETTERS[ vertex.names ]),
-                fontface = "bold") +
-  theme_blank()
-

-
-
-

geom_nodelabel

-

If you prefer to use the geom_label geom recently introduced in ggplot2, ggnetwork also supports these through the nodelabel geom:

-
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
-  geom_edges(color = "black") +
-  geom_nodelabel(aes(color = family, label = LETTERS[ vertex.names ]),
-                 fontface = "bold") +
-  theme_blank()
-

-
-
-

geom_nodetext_repel and geom_nodelabel_repel

-

ggnetwork supports the repulsive label functions introduced by the ggrepel package, which allows to label nodes with non-overlapping annotations. Simply add _repel to either geom_nodetext or geom_nodelabel to use that functionality:

-
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
-  geom_edges(color = "black") +
-  geom_nodelabel_repel(aes(color = family, label = LETTERS[ vertex.names ]),
-                       fontface = "bold", box.padding = unit(1, "lines")) +
-  geom_nodes(color = "black", size = 8) +
-  theme_blank()
-

-
-
-

geom_edgetext and geom_edgelabel

-

Let’s now add edge labels. These are plotted at mid-distance of the nodes that the edges connect by the edgetext geom, which works exactly like geom_label, except that its default arguments do not draw a border around the labels. Here’s an example where we map the day edge attribute to edge labels:

-
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
-  geom_edges(aes(linetype = type), color = "grey75") +
-  geom_nodes(color = "gold", size = 8) +
-  geom_nodetext(aes(label = LETTERS[ vertex.names ])) +
-  geom_edgetext(aes(label = day), color = "white", fill = "grey25") +
-  theme_minimal() +
-  theme(axis.text = element_blank(),
-        axis.title = element_blank(),
-        panel.background = element_rect(fill = "grey25"),
-        panel.grid = element_blank())
-

-

The edgelabel geom is just an alias of the edgetext geom. Note that these geoms are unlikely to produce adequate results if the edges produced by geom_edges are curved.

-
-
-

geom_edgetext_repel and geom_edgelabel_repel

-

As you would do with nodes, simply add _repel to either geom_edgetext or geom_edgelabel to draw repulsive edge labels:

-
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
-  geom_edges(aes(linetype = type), color = "grey75") +
-  geom_nodes(color = "gold", size = 8) +
-  geom_nodetext(aes(label = LETTERS[ vertex.names ])) +
-  geom_edgetext_repel(aes(label = day), color = "white", fill = "grey25",
-                      box.padding = unit(1, "lines")) +
-  theme_minimal() +
-  theme(axis.text = element_blank(),
-        axis.title = element_blank(),
-        panel.background = element_rect(fill = "grey25"),
-        panel.grid = element_blank())
-

-
-
-
-

More plotting parameters

-

This section presents some rather experimental features of ggnetwork.

-
-

Edge arrows

-

ggnetwork uses code by Heike Hoffmann to better show arrows in directed graphs. To illustrate this, we will need a directed graph example, so let’s use the first of the seven emon networks bundled in the network package:

-
data(emon)
-emon[[1]]
-
##  Network attributes:
-##   vertices = 14 
-##   directed = TRUE 
-##   hyper = FALSE 
-##   loops = FALSE 
-##   multiple = FALSE 
-##   total edges= 83 
-##     missing edges= 0 
-##     non-missing edges= 83 
-## 
-##  Vertex attribute names: 
-##     Command.Rank.Score Decision.Rank.Score Formalization Location Paid.Staff Sponsorship vertex.names Volunteer.Staff 
-## 
-##  Edge attribute names: 
-##     Frequency
-

If this network is passed to ggnetwork without any further plotting parameter, the result will feature “shortened” edges that do not reach their receiver nodes:

-

-

This is because directed networks are expected to be plotted with edge arrows indicating the directedness of each edge. Adding edge arrows with geom_edges works through the same call to the arrow function that is supported by geom_segment:

-
ggplot(emon[[1]], aes(x = x, y = y, xend = xend, yend = yend)) +
-  geom_edges(arrow = arrow(length = unit(6, "pt"), type = "closed")) +
-  geom_nodes(color = "tomato", size = 4) +
-  theme_blank()
-

-

The slightly shortened edges avoid overplotting the edge arrows and the nodes. The amount of “edge shortening” can be set through the arrow.gap parameter of ggnetwork, which defaults to 0 when the network is undirected and 0.025 when it is. This parameter might need adjustment depending on the size of the nodes, and it will probably not manage to avoid any overplotting when the size of the nodes is not constant.

-
-
-

Edge weights

-

ggnetwork can use an edge attribute as edge weights when computing the network layout. The name of that edge attribute should be passed to the weights argument for that to happen, as in this example, which will produce different layouts than if weights had been left set to NULL (the default):

-
ggnetwork(emon[[1]], weights = "Frequency")
-

The Kamada-Kawai is one example of a network layout that supports edge weights. The user should refer to the documentation of each network layout to understand which of these can make use of edge weights.

-

If ggnetwork finds duplicated edges in a network, it will return a warning, as these edges should probably have been converted to single weighted edges for adequate plotting.

-
-
-

Node faceting

-

In order for ggnetwork to operate correctly with faceted plots, the by argument, which is NULL by default, can be set to the name of an edge attribute. The result will be a longer data frame that can be plotted with either facet_wrap or facet_grid, as in the example below, where the faceting variable, the Frequency edge attribute, has to be specified twice (once to ggnetwork, once to facet_wrap):

-
ggplot(ggnetwork(emon[[1]], arrow.gap = 0.04, by = "Frequency"),
-       aes(x = x, y = y, xend = xend, yend = yend)) +
-  geom_edges(arrow = arrow(length = unit(6, "pt"), type = "closed"),
-             aes(color = Sponsorship)) +
-  geom_nodes(aes(color = Sponsorship), size = 4) +
-  facet_wrap(~ Frequency) +
-  theme_facet()
-

-

The by argument is basically an attempt to bring minimal support for temporal networks in ggnetwork. It will systematically show all nodes in all plot facets, using the same coordinates in every facet. For more advanced plots of dynamic networks, the user should turn to the ndtv and tsna packages.

-

The example above also shows how to use a vertex attribute as part of the aesthetics of the edges. Given how ggnetwork operates, these vertex attributes will always be those of the sender node.

-

Last, the example also shows that ggnetwork comes with a theme called theme_facet. This theme is a variation of the previously mentioned theme_blank that preserves its facet boxes:

-
theme_facet
-
## function(base_size = 12, base_family = "", ...) {
-##   theme_blank(base_size = base_size, base_family = base_family) +
-##     ggplot2::theme(
-##       panel.border = ggplot2::element_rect(fill = NA, color = "grey50"),
-##       ...
-##     )
-## }
-## <environment: namespace:ggnetwork>
-
-
-
-

Additional methods

-

Since ggnetwork works entirely through ggplot2, all ggplot2 methods apply:

-
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
-  geom_edges(aes(linetype = type), color = "grey50") +
-  geom_nodes(aes(x, y, color = family, size = 1.5 * importance)) +
-  geom_nodetext(aes(label = LETTERS[ vertex.names ], size = 0.5 * importance)) +
-  geom_edgetext(aes(label = day), color = "grey25") +
-  scale_color_brewer(palette = "Set2") +
-  scale_size_area("importance", breaks = 1:3, max_size = 9) +
-  theme_blank()
-

-

Similarly, it is possible to use any of the geometries more than once per plot:

-
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
-  geom_edges(color = "grey50", alpha = 0.5) +
-  geom_nodes(aes(x, y, color = family, size = 5.5 * importance), alpha = 0.5) +
-  geom_nodes(aes(x, y, color = family, size = 1.5 * importance)) +
-  scale_color_brewer(palette = "Set1") +
-  guides(size = FALSE) +
-  theme_blank()
-

-

Last, all geoms provided by ggnetwork can be subsetted through the data argument, just as any ggplot2 geom, and as in the example below, which draws only a subset of all node labels:

-
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
-  geom_edges(color = "grey50", alpha = 0.5) +
-  geom_nodes(aes(x, y, color = family), size = 3) +
-  geom_nodelabel_repel(aes(label = vertex.names),
-                       box.padding = unit(1, "lines"),
-                       data = function(x) { x[ x$family == "a", ]}) +
-  scale_color_brewer(palette = "Set1") +
-  theme_blank()
-

-
-

Last printed on Mar 25, 2016, using ggnetwork version 0.4.

-
- - - - -
- - - - - - - - From 13ebce1fa06533de2877855efa96e47e0b77fc2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 16:13:40 +0200 Subject: [PATCH 12/48] roxygen update --- man/scale_safely.Rd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/man/scale_safely.Rd b/man/scale_safely.Rd index f6c31fe..27dfe3b 100644 --- a/man/scale_safely.Rd +++ b/man/scale_safely.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/utilities.R \name{scale_safely} \alias{scale_safely} -\title{Rescale `x` to (0, 1), except if `x` is constant} +\title{Rescale x to (0, 1), except if x is constant} \usage{ scale_safely(x, scale = diff(range(x))) } @@ -13,9 +13,10 @@ scale_safely(x, scale = diff(range(x))) } \value{ The rescaled vector, coerced to a vector if necessary. +If the original vector was constant, all of its values are replaced by 0.5. } \description{ -Discussed in PR #32. +Discussed in PR #32: https://github.com/briatte/ggnetwork/pull/32 } \author{ Kipp Johnson From fe8004eb8e185d3fdc8213de9f5c8b15b61c69cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 16:14:00 +0200 Subject: [PATCH 13/48] fix "DESCRIPTION meta-information ... NOTE" --- DESCRIPTION | 2 -- 1 file changed, 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 196a4fb..00da44e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -33,5 +33,3 @@ Suggests: igraph, knitr, testthat -Enhances: - ggplot2 From afdd8694509075e96275814e2f510f4ce96a6504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 16:19:03 +0200 Subject: [PATCH 14/48] restyle; try to fix "Undefined global functions or variables: y" --- R/fortify-igraph.R | 77 +++++++++++++++++++++---------------------- man/fortify.igraph.Rd | 4 +-- 2 files changed, 39 insertions(+), 42 deletions(-) diff --git a/R/fortify-igraph.R b/R/fortify-igraph.R index da1b409..d24dcfc 100644 --- a/R/fortify-igraph.R +++ b/R/fortify-igraph.R @@ -2,8 +2,8 @@ #' #' @param model an object of class \code{\link[igraph:igraph-package]{igraph}} #' @param data not used by this method. -#' @param layout a function call to an -#' \code{\link[igraph:igraph-package]{igraph}} layout function, such as +#' @param layout a function call to an +#' \code{\link[igraph:igraph-package]{igraph}} layout function, such as #' \code{\link[igraph]{layout_nicely}} (the default), or a 2 column matrix #' giving the x and y coordinates for the vertices. #' See \code{\link[igraph]{layout_}} for details. @@ -19,30 +19,28 @@ #' @method fortify igraph #' @importFrom utils installed.packages #' @export -fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), +fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), arrow.gap = ifelse(igraph::is.directed(x), 0.025, 0), by = NULL, ...) { + x <- model - - x = model - # node placement if (class(layout) == "matrix" && - nrow(layout) == igraph::gorder(x) && - ncol(layout) == 2) { - nodes = layout[, 1:2 ] + nrow(layout) == igraph::gorder(x) && + ncol(layout) == 2) { + nodes <- layout[, 1:2 ] } else { nodes <- igraph::layout_(x, layout, ...) } - + # store coordinates - nodes = data.frame(nodes) - names(nodes) = c("x", "y") - + nodes <- data.frame(nodes) + names(nodes) <- c("x", "y") + # rescale coordinates nodes$x <- scale_safely(nodes$x) nodes$y <- scale_safely(nodes$y) - + # import vertex attributes if (length(igraph::list.vertex.attributes(x))) { nodes <- cbind( @@ -56,24 +54,24 @@ fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), ) } - + # edge list edges <- igraph::as_edgelist(x, names = F) - + # edge list (if there are duplicated rows) if (nrow(edges[, 1:2]) > nrow(unique(edges[, 1:2]))) { warning("duplicated edges detected") } - - edges = data.frame(nodes[edges[, 1], 1:2], nodes[edges[, 2], 1:2]) - names(edges) = c("x", "y", "xend", "yend") - + + edges <- data.frame(nodes[edges[, 1], 1:2], nodes[edges[, 2], 1:2]) + names(edges) <- c("x", "y", "xend", "yend") + # arrow gap (thanks to @heike and @ethen8181 for their work on this issue) if (arrow.gap > 0) { - x.length = with(edges, xend - x) - y.length = with(edges, yend - y) - arrow.gap = with(edges, arrow.gap / sqrt(x.length ^ 2 + y.length ^ 2)) - edges = transform( + x.length <- edges$xend - edges$x + y.length <- edges$yend - edges$y + arrow.gap <- with(edges, arrow.gap / sqrt(x.length^2 + y.length^2)) + edges <- transform( edges, # x = x + arrow.gap * x.length, # y = y + arrow.gap * y.length, @@ -81,7 +79,7 @@ fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), yend = y + (1 - arrow.gap) * y.length ) } - + # import edge attributes if (length(igraph::list.edge.attributes(x))) { edges <- cbind( @@ -91,35 +89,34 @@ fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), FUN = igraph::get.edge.attribute, graph = x, USE.NAMES = T - ) ) + ) } # merge edges and nodes data - edges = merge(nodes, edges, by = c("x", "y"), all = TRUE) - + edges <- merge(nodes, edges, by = c("x", "y"), all = TRUE) + # add missing columns to nodes data - nodes$xend = nodes$x - nodes$yend = nodes$y - names(nodes) = names(edges)[1:ncol(nodes)] - + nodes$xend <- nodes$x + nodes$yend <- nodes$y + names(nodes) <- names(edges)[1:ncol(nodes)] + # make nodes data of identical dimensions to edges data missing.cols <- names(edges)[which(!(names(edges) %in% names(nodes)))] nodes[missing.cols] <- NA - + # panelize nodes (for temporal networks) if (!is.null(by)) { - nodes = lapply(sort(unique(edges[, by ])), function(x) { - y = nodes - y[, by ] = x + nodes <- lapply(sort(unique(edges[, by ])), function(x) { + y <- nodes + y[, by ] <- x y }) - nodes = do.call(rbind, nodes) + nodes <- do.call(rbind, nodes) } - + # return a data frame with network.size(x) + network.edgecount(x) rows, # or length(unique(edges[, by ])) * network.size(x) + network.edgecount(x) # rows if the nodes have been panelized unique(rbind(nodes, edges[ !is.na(edges$xend), ])) - -} +} \ No newline at end of file diff --git a/man/fortify.igraph.Rd b/man/fortify.igraph.Rd index b6c8bb9..1fdac4a 100644 --- a/man/fortify.igraph.Rd +++ b/man/fortify.igraph.Rd @@ -12,8 +12,8 @@ \item{data}{not used by this method.} -\item{layout}{a function call to an -\code{\link[igraph:igraph-package]{igraph}} layout function, such as +\item{layout}{a function call to an +\code{\link[igraph:igraph-package]{igraph}} layout function, such as \code{\link[igraph]{layout_nicely}} (the default), or a 2 column matrix giving the x and y coordinates for the vertices. See \code{\link[igraph]{layout_}} for details.} From fce21efd9fa5e0720214fd454980818d909f5810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 16:21:21 +0200 Subject: [PATCH 15/48] usethis::use_tidy_style() --- R/fortify-igraph.R | 2 +- R/fortify-network.R | 103 ++++++----- R/geom-edges.R | 264 ++++++++++++++-------------- R/geom-nodes.R | 302 ++++++++++++++++---------------- R/ggnetwork.R | 14 +- R/utilities.R | 2 +- tests/testthat/test-fortify.R | 4 - tests/testthat/test-geoms.R | 39 ++--- tests/testthat/test-ggnetwork.R | 5 +- tests/testthat/test-utilities.R | 4 - 10 files changed, 358 insertions(+), 381 deletions(-) diff --git a/R/fortify-igraph.R b/R/fortify-igraph.R index d24dcfc..6d7f91c 100644 --- a/R/fortify-igraph.R +++ b/R/fortify-igraph.R @@ -119,4 +119,4 @@ fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), # or length(unique(edges[, by ])) * network.size(x) + network.edgecount(x) # rows if the nodes have been panelized unique(rbind(nodes, edges[ !is.na(edges$xend), ])) -} \ No newline at end of file +} diff --git a/R/fortify-network.R b/R/fortify-network.R index 6ada7f1..13b3abe 100644 --- a/R/fortify-network.R +++ b/R/fortify-network.R @@ -64,40 +64,50 @@ if (getRversion() >= "2.15.1") { #' ggnetwork(emon[[1]], layout = "kamadakawai", weights = "Frequency") #' #' # plot example with straight edges -#' ggplot(ggnetwork(emon[[1]], layout = "kamadakawai", arrow.gap = 0.025), -#' aes(x, y, xend = xend, yend = yend)) + +#' ggplot( +#' ggnetwork(emon[[1]], layout = "kamadakawai", arrow.gap = 0.025), +#' aes(x, y, xend = xend, yend = yend) +#' ) + #' geom_edges(aes(color = Frequency), -#' arrow = arrow(length = unit(10, "pt"), type = "closed")) + +#' arrow = arrow(length = unit(10, "pt"), type = "closed") +#' ) + #' geom_nodes(aes(size = Formalization)) + #' scale_color_gradient(low = "grey50", high = "tomato") + #' scale_size_area(breaks = 1:3) + #' theme_blank() #' #' # plot example with curved edges -#' ggplot(ggnetwork(emon[[1]], layout = "kamadakawai", arrow.gap = 0.025), -#' aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(aes(color = Frequency), curvature = 0.1, -#' arrow = arrow(length = unit(10, "pt"), type = "open")) + +#' ggplot( +#' ggnetwork(emon[[1]], layout = "kamadakawai", arrow.gap = 0.025), +#' aes(x, y, xend = xend, yend = yend) +#' ) + +#' geom_edges(aes(color = Frequency), +#' curvature = 0.1, +#' arrow = arrow(length = unit(10, "pt"), type = "open") +#' ) + #' geom_nodes(aes(size = Formalization)) + #' scale_color_gradient(low = "grey50", high = "tomato") + #' scale_size_area(breaks = 1:3) + #' theme_blank() #' #' # facet by edge attribute -#' ggplot(ggnetwork(emon[[1]], arrow.gap = 0.02, by = "Frequency"), -#' aes(x, y, xend = xend, yend = yend)) + +#' ggplot( +#' ggnetwork(emon[[1]], arrow.gap = 0.02, by = "Frequency"), +#' aes(x, y, xend = xend, yend = yend) +#' ) + #' geom_edges(arrow = arrow(length = unit(5, "pt"), type = "closed")) + #' geom_nodes() + #' theme_blank() + #' facet_grid(. ~ Frequency, labeller = label_both) #' #' # user-provided layout -#' ggplot(ggnetwork(emon[[1]], layout = matrix(runif(28), ncol = 2)), -#' aes(x, y, xend = xend, yend = yend)) + +#' ggplot( +#' ggnetwork(emon[[1]], layout = matrix(runif(28), ncol = 2)), +#' aes(x, y, xend = xend, yend = yend) +#' ) + #' geom_edges(arrow = arrow(length = unit(5, "pt"), type = "closed")) + #' geom_nodes() + #' theme_blank() -#' #' } #' @export fortify.network <- function(model, data = NULL, @@ -105,25 +115,25 @@ fortify.network <- function(model, data = NULL, arrow.gap = ifelse(network::is.directed(model), 0.025, 0), by = NULL, ...) { - x = model + x <- model # node placement if (class(layout) == "matrix" && - nrow(layout) == network::network.size(x) && - ncol(layout) == 2) { - nodes = layout[, 1:2 ] + nrow(layout) == network::network.size(x) && + ncol(layout) == 2) { + nodes <- layout[, 1:2 ] } else { - layout = paste0("gplot.layout.", layout) + layout <- paste0("gplot.layout.", layout) ns <- loadNamespace("sna") - if (!exists(layout, envir=ns, inherits=FALSE)) { + if (!exists(layout, envir = ns, inherits = FALSE)) { stop("unsupported layout") } - nodes = do.call( utils::getFromNamespace(layout, ns), list(x, layout.par = list(...))) + nodes <- do.call(utils::getFromNamespace(layout, ns), list(x, layout.par = list(...))) } # store coordinates - nodes = data.frame(nodes) - names(nodes) = c("x", "y") + nodes <- data.frame(nodes) + names(nodes) <- c("x", "y") # rescale coordinates nodes$x <- scale_safely(nodes$x) @@ -131,27 +141,27 @@ fortify.network <- function(model, data = NULL, # import vertex attributes for (y in network::list.vertex.attributes(x)) { - nodes = cbind(nodes, network::get.vertex.attribute(x, y)) - names(nodes)[ncol(nodes)] = y + nodes <- cbind(nodes, network::get.vertex.attribute(x, y)) + names(nodes)[ncol(nodes)] <- y } # edge list - edges = network::as.matrix.network.edgelist(x, attrname = weights) + edges <- network::as.matrix.network.edgelist(x, attrname = weights) # edge list (if there are duplicated rows) if (nrow(edges[, 1:2, drop = FALSE]) > nrow(unique(edges[, 1:2, drop = FALSE]))) { warning("duplicated edges detected") } - edges = data.frame(nodes[edges[, 1], 1:2], nodes[edges[, 2], 1:2]) - names(edges) = c("x", "y", "xend", "yend") + edges <- data.frame(nodes[edges[, 1], 1:2], nodes[edges[, 2], 1:2]) + names(edges) <- c("x", "y", "xend", "yend") # arrow gap (thanks to @heike and @ethen8181 for their work on this issue) if (arrow.gap > 0) { - x.length = with(edges, xend - x) - y.length = with(edges, yend - y) - arrow.gap = with(edges, arrow.gap / sqrt(x.length ^ 2 + y.length ^ 2)) - edges = transform( + x.length <- with(edges, xend - x) + y.length <- with(edges, yend - y) + arrow.gap <- with(edges, arrow.gap / sqrt(x.length^2 + y.length^2)) + edges <- transform( edges, # x = x + arrow.gap * x.length, # y = y + arrow.gap * y.length, @@ -162,33 +172,33 @@ fortify.network <- function(model, data = NULL, # import edge attributes for (y in network::list.edge.attributes(x)) { - edges = cbind(edges, network::get.edge.attribute(x, y)) - names(edges)[ncol(edges)] = y + edges <- cbind(edges, network::get.edge.attribute(x, y)) + names(edges)[ncol(edges)] <- y } - if (nrow(edges)!=0) { + if (nrow(edges) != 0) { # merge edges and nodes data - edges = merge(nodes, edges, by = c("x", "y"), all = TRUE) - + edges <- merge(nodes, edges, by = c("x", "y"), all = TRUE) + # add missing columns to nodes data - nodes$xend = nodes$x - nodes$yend = nodes$y - names(nodes) = names(edges)[1:ncol(nodes)] + nodes$xend <- nodes$x + nodes$yend <- nodes$y + names(nodes) <- names(edges)[1:ncol(nodes)] # make nodes data of identical dimensions to edges data for (y in names(edges)[(1 + ncol(nodes)):ncol(edges)]) { - nodes = cbind(nodes, NA) - names(nodes)[ncol(nodes)] = y + nodes <- cbind(nodes, NA) + names(nodes)[ncol(nodes)] <- y } # panelize nodes (for temporal networks) if (!is.null(by)) { - nodes = lapply(sort(unique(edges[, by ])), function(x) { - y = nodes - y[, by ] = x + nodes <- lapply(sort(unique(edges[, by ])), function(x) { + y <- nodes + y[, by ] <- x y }) - nodes = do.call(rbind, nodes) + nodes <- do.call(rbind, nodes) } # return a data frame with network.size(x) + network.edgecount(x) rows, @@ -197,9 +207,8 @@ fortify.network <- function(model, data = NULL, return(unique(rbind(nodes, edges[ !is.na(edges$xend), ]))) } else { # add missing columns to nodes data - nodes$xend = nodes$x - nodes$yend = nodes$y + nodes$xend <- nodes$x + nodes$yend <- nodes$y return(nodes) } - } diff --git a/R/geom-edges.R b/R/geom-edges.R index 2c4f2fc..71ed1e3 100644 --- a/R/geom-edges.R +++ b/R/geom-edges.R @@ -13,61 +13,70 @@ #' @examples #' if (require(network) && require(sna)) { #' -#' # rerun if the example does not produce reciprocated ties -#' n <- network(rgraph(10, tprob = 0.2), directed = TRUE) +#' # rerun if the example does not produce reciprocated ties +#' n <- network(rgraph(10, tprob = 0.2), directed = TRUE) #' -#' # just edges -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(size = 1, colour = "steelblue") + -#' theme_blank() +#' # just edges +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(size = 1, colour = "steelblue") + +#' theme_blank() #' -#' # with nodes -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(size = 1, colour = "steelblue") + -#' geom_nodes(size = 3, colour = "steelblue") + -#' theme_blank() +#' # with nodes +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(size = 1, colour = "steelblue") + +#' geom_nodes(size = 3, colour = "steelblue") + +#' theme_blank() #' -#' # with arrows -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(size = 1, colour = "steelblue", -#' arrow = arrow(length = unit(0.5, "lines"), type = "closed")) + -#' geom_nodes(size = 3, colour = "steelblue") + -#' theme_blank() +#' # with arrows +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges( +#' size = 1, colour = "steelblue", +#' arrow = arrow(length = unit(0.5, "lines"), type = "closed") +#' ) + +#' geom_nodes(size = 3, colour = "steelblue") + +#' theme_blank() #' -#' # with curvature -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(size = 1, colour = "steelblue", curvature = 0.15, -#' arrow = arrow(length = unit(0.5, "lines"), type = "closed")) + -#' geom_nodes(size = 3, colour = "steelblue") + -#' theme_blank() +#' # with curvature +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges( +#' size = 1, colour = "steelblue", curvature = 0.15, +#' arrow = arrow(length = unit(0.5, "lines"), type = "closed") +#' ) + +#' geom_nodes(size = 3, colour = "steelblue") + +#' theme_blank() #' -#' # arbitrary categorical edge attribute -#' e <- sample(letters[ 1:2 ], network.edgecount(n), replace = TRUE) -#' set.edge.attribute(n, "type", e) -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(aes(linetype = type), size = 1, curvature = 0.15, -#' arrow = arrow(length = unit(0.5, "lines"), type = "closed")) + -#' geom_nodes(size = 3, colour = "steelblue") + -#' theme_blank() +#' # arbitrary categorical edge attribute +#' e <- sample(letters[ 1:2 ], network.edgecount(n), replace = TRUE) +#' set.edge.attribute(n, "type", e) +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(aes(linetype = type), +#' size = 1, curvature = 0.15, +#' arrow = arrow(length = unit(0.5, "lines"), type = "closed") +#' ) + +#' geom_nodes(size = 3, colour = "steelblue") + +#' theme_blank() #' -#' # arbitrary numeric edge attribute (signed network) -#' e <- sample(-2:2, network.edgecount(n), replace = TRUE) -#' set.edge.attribute(n, "weight", e) -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(aes(colour = weight), curvature = 0.15, -#' arrow = arrow(length = unit(0.5, "lines"), type = "closed")) + -#' geom_nodes(size = 3, colour = "grey50") + -#' scale_colour_gradient(low = "steelblue", high = "tomato") + -#' theme_blank() -#' -#' # draw only a subset of all edges -#' positive_weight <- function(x) { x[ x$weight >= 0, ] } -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(aes(colour = weight), data = positive_weight) + -#' geom_nodes(size = 4, colour = "grey50") + -#' scale_colour_gradient(low = "gold", high = "tomato") + -#' theme_blank() +#' # arbitrary numeric edge attribute (signed network) +#' e <- sample(-2:2, network.edgecount(n), replace = TRUE) +#' set.edge.attribute(n, "weight", e) +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(aes(colour = weight), +#' curvature = 0.15, +#' arrow = arrow(length = unit(0.5, "lines"), type = "closed") +#' ) + +#' geom_nodes(size = 3, colour = "grey50") + +#' scale_colour_gradient(low = "steelblue", high = "tomato") + +#' theme_blank() #' +#' # draw only a subset of all edges +#' positive_weight <- function(x) { +#' x[ x$weight >= 0, ] +#' } +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(aes(colour = weight), data = positive_weight) + +#' geom_nodes(size = 4, colour = "grey50") + +#' scale_colour_gradient(low = "gold", high = "tomato") + +#' theme_blank() #' } #' @export geom_edges <- function(mapping = NULL, data = NULL, @@ -75,17 +84,16 @@ geom_edges <- function(mapping = NULL, data = NULL, curvature = 0, angle = 90, ncp = 5, na.rm = FALSE, show.legend = NA, inherit.aes = TRUE, ...) { - if (!curvature) { - geom = ggplot2::GeomSegment - params = list( + geom <- ggplot2::GeomSegment + params <- list( arrow = arrow, na.rm = na.rm, ... ) } else { - geom = ggplot2::GeomCurve - params = list( + geom <- ggplot2::GeomCurve + params <- list( arrow = arrow, curvature = curvature, angle = angle, @@ -105,7 +113,6 @@ geom_edges <- function(mapping = NULL, data = NULL, inherit.aes = inherit.aes, params = params ) - } # note: the nudge_x,nudge_y arguments below are duplicated from the original @@ -126,29 +133,29 @@ geom_edges <- function(mapping = NULL, data = NULL, #' @importFrom ggplot2 unit position_nudge layer GeomLabel #' @examples #' if (require(network) && require(sna)) { +#' data(flo, package = "network") +#' n <- network(flo, directed = FALSE) #' -#' data(flo, package = "network") -#' n <- network(flo, directed = FALSE) -#' -#' # arbitrary categorical edge attribute -#' e <- sample(letters[ 1:4 ], network.edgecount(n), replace = TRUE) -#' set.edge.attribute(n, "type", e) +#' # arbitrary categorical edge attribute +#' e <- sample(letters[ 1:4 ], network.edgecount(n), replace = TRUE) +#' set.edge.attribute(n, "type", e) #' -#' # with labelled edges -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(aes(colour = type)) + -#' geom_edgetext(aes(label = type, colour = type)) + -#' geom_nodes(size = 4, colour = "grey50") + -#' theme_blank() -#' -#' # label only a subset of all edges with arbitrary symbol -#' edge_type <- function(x) { x[ x$type == "a", ] } -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges() + -#' geom_edgetext(label = "=", data = edge_type) + -#' geom_nodes(size = 4, colour = "grey50") + -#' theme_blank() +#' # with labelled edges +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(aes(colour = type)) + +#' geom_edgetext(aes(label = type, colour = type)) + +#' geom_nodes(size = 4, colour = "grey50") + +#' theme_blank() #' +#' # label only a subset of all edges with arbitrary symbol +#' edge_type <- function(x) { +#' x[ x$type == "a", ] +#' } +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges() + +#' geom_edgetext(label = "=", data = edge_type) + +#' geom_nodes(size = 4, colour = "grey50") + +#' theme_blank() #' } #' @export geom_edgetext <- function(mapping = NULL, data = NULL, @@ -201,54 +208,57 @@ geom_edgetext <- function(mapping = NULL, data = NULL, #' @importFrom ggrepel GeomLabelRepel #' @examples #' if (require(network) && require(sna)) { +#' data(flo, package = "network") +#' n <- network(flo, directed = FALSE) #' -#' data(flo, package = "network") -#' n <- network(flo, directed = FALSE) -#' -#' # arbitrary categorical edge attribute -#' e <- sample(1:4, network.edgecount(n), replace = TRUE) -#' set.edge.attribute(n, "day", e) -#' -#' # with repulsive edge labels -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges() + -#' geom_edgetext_repel(aes(label = day), box.padding = unit(0.5, "lines")) + -#' geom_nodes(size = 4, colour = "grey50") + -#' theme_blank() +#' # arbitrary categorical edge attribute +#' e <- sample(1:4, network.edgecount(n), replace = TRUE) +#' set.edge.attribute(n, "day", e) #' -#' # repulsive edge labels for only a subset of all edges -#' edge_day <- function(x) { x[ x$day > 2, ] } -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(aes(colour = cut(day, (4:0)[ -3 ]))) + -#' geom_edgetext_repel(aes(label = paste("day", day), -#' colour = cut(day, (4:0)[ -3 ])), data = edge_day) + -#' geom_nodes(size = 4, colour = "grey50") + -#' scale_colour_manual("day", labels = c("old ties", "day 3", "day 4"), -#' values = c("grey50", "gold", "tomato")) + -#' theme_blank() +#' # with repulsive edge labels +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges() + +#' geom_edgetext_repel(aes(label = day), box.padding = unit(0.5, "lines")) + +#' geom_nodes(size = 4, colour = "grey50") + +#' theme_blank() #' +#' # repulsive edge labels for only a subset of all edges +#' edge_day <- function(x) { +#' x[ x$day > 2, ] +#' } +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(aes(colour = cut(day, (4:0)[ -3 ]))) + +#' geom_edgetext_repel(aes( +#' label = paste("day", day), +#' colour = cut(day, (4:0)[ -3 ]) +#' ), data = edge_day) + +#' geom_nodes(size = 4, colour = "grey50") + +#' scale_colour_manual("day", +#' labels = c("old ties", "day 3", "day 4"), +#' values = c("grey50", "gold", "tomato") +#' ) + +#' theme_blank() #' } #' @export geom_edgetext_repel <- function( - mapping = NULL, data = NULL, - parse = FALSE, - ..., - box.padding = unit(0.25, "lines"), - label.padding = unit(0.25, "lines"), - point.padding = unit(1e-6, "lines"), - label.r = unit(0.15, "lines"), - label.size = 0.25, - segment.colour = "#666666", - segment.size = 0.5, - arrow = NULL, - force = 1, - max.iter = 2000, - nudge_x = 0, - nudge_y = 0, - na.rm = FALSE, - show.legend = NA, - inherit.aes = TRUE -) { + mapping = NULL, data = NULL, + parse = FALSE, + ..., + box.padding = unit(0.25, "lines"), + label.padding = unit(0.25, "lines"), + point.padding = unit(1e-6, "lines"), + label.r = unit(0.15, "lines"), + label.size = 0.25, + segment.colour = "#666666", + segment.size = 0.5, + arrow = NULL, + force = 1, + max.iter = 2000, + nudge_x = 0, + nudge_y = 0, + na.rm = FALSE, + show.legend = NA, + inherit.aes = TRUE) { layer( data = data, mapping = mapping, @@ -259,9 +269,9 @@ geom_edgetext_repel <- function( inherit.aes = inherit.aes, params = list( parse = parse, - box.padding = box.padding, + box.padding = box.padding, label.padding = label.padding, - point.padding = point.padding, + point.padding = point.padding, label.r = label.r, label.size = label.size, segment.colour = segment.colour, @@ -289,19 +299,19 @@ geom_edgelabel_repel <- geom_edgetext_repel #' @keywords internal StatEdges <- ggplot2::ggproto("StatEdges", ggplot2::Stat, - compute_layer = function(data, scales, params) { - unique(subset(data, !(x == xend & y == yend))) - } + compute_layer = function(data, scales, params) { + unique(subset(data, !(x == xend & y == yend))) + } ) #' @importFrom ggplot2 ggproto #' @keywords internal StatMidEdges <- ggplot2::ggproto("StatMidEdges", ggplot2::Stat, - compute_layer = function(data, scales, params) { - data = subset(data, !(x == xend & y == yend)) - data$x = (data$x + data$xend) / 2 - data$y = (data$y + data$yend) / 2 - unique(subset(data, select = c(-xend, -yend))) - } + compute_layer = function(data, scales, params) { + data <- subset(data, !(x == xend & y == yend)) + data$x <- (data$x + data$xend) / 2 + data$y <- (data$y + data$yend) / 2 + unique(subset(data, select = c(-xend, -yend))) + } ) diff --git a/R/geom-nodes.R b/R/geom-nodes.R index 1bdd3c0..b93bad1 100644 --- a/R/geom-nodes.R +++ b/R/geom-nodes.R @@ -6,43 +6,40 @@ #' @importFrom ggplot2 layer GeomPoint #' @examples #' if (require(network) && require(sna)) { +#' data(flo, package = "network") +#' n <- network(flo, directed = FALSE) #' -#' data(flo, package = "network") -#' n <- network(flo, directed = FALSE) +#' # just nodes +#' ggplot(n, aes(x, y)) + +#' geom_nodes(size = 3, shape = 21, colour = "steelblue") + +#' theme_blank() #' -#' # just nodes -#' ggplot(n, aes(x, y)) + -#' geom_nodes(size = 3, shape = 21, colour = "steelblue") + -#' theme_blank() +#' # with edges +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(colour = "steelblue") + +#' geom_nodes(size = 3, shape = 21, colour = "steelblue", fill = "white") + +#' theme_blank() #' -#' # with edges -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(colour = "steelblue") + -#' geom_nodes(size = 3, shape = 21, colour = "steelblue", fill = "white") + -#' theme_blank() +#' # with nodes sized according to degree centrality +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(colour = "steelblue") + +#' geom_nodes(size = degree(n), shape = 21, colour = "steelblue", fill = "white") + +#' theme_blank() #' -#' # with nodes sized according to degree centrality -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(colour = "steelblue") + -#' geom_nodes(size = degree(n), shape = 21, colour = "steelblue", fill = "white") + -#' theme_blank() -#' -#' # with nodes colored according to betweenness centrality -#' -#' n %v% "betweenness" <- betweenness(flo) -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(colour = "grey50") + -#' geom_nodes(aes(colour = betweenness), size = 3) + -#' scale_colour_gradient(low = "gold", high = "tomato") + -#' theme_blank() + -#' theme(legend.position = "bottom") +#' # with nodes colored according to betweenness centrality #' +#' n %v% "betweenness" <- betweenness(flo) +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(colour = "grey50") + +#' geom_nodes(aes(colour = betweenness), size = 3) + +#' scale_colour_gradient(low = "gold", high = "tomato") + +#' theme_blank() + +#' theme(legend.position = "bottom") #' } #' @export geom_nodes <- function(mapping = NULL, data = NULL, position = "identity", na.rm = FALSE, show.legend = NA, inherit.aes = TRUE, ...) { - ggplot2::layer( data = data, mapping = mapping, @@ -56,7 +53,6 @@ geom_nodes <- function(mapping = NULL, data = NULL, ... ) ) - } # note: the nudge_x,nudge_y arguments below are duplicated from the original @@ -75,27 +71,25 @@ geom_nodes <- function(mapping = NULL, data = NULL, #' ## geom_nodetext examples #' #' if (require(network) && require(sna)) { +#' n <- network(rgraph(10, tprob = 0.2), directed = FALSE) #' -#' n <- network(rgraph(10, tprob = 0.2), directed = FALSE) -#' -#' # just node labels -#' ggplot(n, aes(x, y)) + -#' geom_nodetext(aes(label = vertex.names)) + -#' theme_blank() +#' # just node labels +#' ggplot(n, aes(x, y)) + +#' geom_nodetext(aes(label = vertex.names)) + +#' theme_blank() #' -#' # with nodes underneath -#' ggplot(n, aes(x, y)) + -#' geom_nodes(colour = "gold", size = 9) + -#' geom_nodetext(aes(label = vertex.names)) + -#' theme_blank() -#' -#' # with nodes and edges -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(colour = "gold") + -#' geom_nodes(colour = "gold", size = 9) + -#' geom_nodetext(aes(label = vertex.names)) + -#' theme_blank() +#' # with nodes underneath +#' ggplot(n, aes(x, y)) + +#' geom_nodes(colour = "gold", size = 9) + +#' geom_nodetext(aes(label = vertex.names)) + +#' theme_blank() #' +#' # with nodes and edges +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(colour = "gold") + +#' geom_nodes(colour = "gold", size = 9) + +#' geom_nodetext(aes(label = vertex.names)) + +#' theme_blank() #' } geom_nodetext <- function(mapping = NULL, data = NULL, @@ -108,15 +102,12 @@ geom_nodetext <- function(mapping = NULL, na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) { - if (!missing(nudge_x) || !missing(nudge_y)) { - if (!missing(position)) { stop("Specify either `position` or `nudge_x`/`nudge_y`", call. = FALSE) } position <- ggplot2::position_nudge(nudge_x, nudge_y) - } ggplot2::layer( @@ -134,7 +125,6 @@ geom_nodetext <- function(mapping = NULL, ... ) ) - } # note: the nudge_x,nudge_y arguments below are duplicated from the original @@ -154,15 +144,14 @@ geom_nodetext <- function(mapping = NULL, #' ## geom_nodetext_repel example #' #' if (require(network) && require(sna)) { -#' -#' n <- network(rgraph(10, tprob = 0.2), directed = FALSE) -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(colour = "steelblue") + -#' geom_nodetext_repel(aes(label = paste("node", vertex.names)), -#' box.padding = unit(1, "lines")) + -#' geom_nodes(colour = "steelblue", size = 3) + -#' theme_blank() -#' +#' n <- network(rgraph(10, tprob = 0.2), directed = FALSE) +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(colour = "steelblue") + +#' geom_nodetext_repel(aes(label = paste("node", vertex.names)), +#' box.padding = unit(1, "lines") +#' ) + +#' geom_nodes(colour = "steelblue", size = 3) + +#' theme_blank() #' } #' @export geom_nodetext_repel <- function(mapping = NULL, @@ -182,29 +171,29 @@ geom_nodetext_repel <- function(mapping = NULL, na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) { - ggplot2::layer(data = data, - mapping = mapping, - stat = StatNodes, - geom = ggrepel::GeomTextRepel, - position = "identity", - show.legend = show.legend, - inherit.aes = inherit.aes, - params = list( - parse = parse, - na.rm = na.rm, - box.padding = box.padding, - point.padding = point.padding, - segment.colour = segment.colour, - segment.size = segment.size, - arrow = arrow, - force = force, - max.iter = max.iter, - nudge_x = nudge_x, - nudge_y = nudge_y, - ... - ) + ggplot2::layer( + data = data, + mapping = mapping, + stat = StatNodes, + geom = ggrepel::GeomTextRepel, + position = "identity", + show.legend = show.legend, + inherit.aes = inherit.aes, + params = list( + parse = parse, + na.rm = na.rm, + box.padding = box.padding, + point.padding = point.padding, + segment.colour = segment.colour, + segment.size = segment.size, + arrow = arrow, + force = force, + max.iter = max.iter, + nudge_x = nudge_x, + nudge_y = nudge_y, + ... + ) ) - } #' @rdname geom_nodetext @@ -215,34 +204,36 @@ geom_nodetext_repel <- function(mapping = NULL, #' ## geom_nodelabel examples #' #' if (require(network) && require(sna)) { +#' data(flo, package = "network") +#' n <- network(flo, directed = FALSE) #' -#' data(flo, package = "network") -#' n <- network(flo, directed = FALSE) -#' -#' # with text labels -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(colour = "grey50") + -#' geom_nodelabel(aes(label = vertex.names)) + -#' theme_blank() +#' # with text labels +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(colour = "grey50") + +#' geom_nodelabel(aes(label = vertex.names)) + +#' theme_blank() #' -#' # with text labels coloured according to degree centrality -#' n %v% "degree" <- degree(n) -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(colour = "grey50") + -#' geom_nodelabel(aes(label = vertex.names, fill = degree)) + -#' scale_fill_gradient(low = "gold", high = "tomato") + -#' theme_blank() +#' # with text labels coloured according to degree centrality +#' n %v% "degree" <- degree(n) +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(colour = "grey50") + +#' geom_nodelabel(aes(label = vertex.names, fill = degree)) + +#' scale_fill_gradient(low = "gold", high = "tomato") + +#' theme_blank() #' -#' # label only a subset of all nodes -#' high_degree <- function(x) { x[ x$degree > median(x$degree), ] } -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(colour = "steelblue") + -#' geom_nodes(aes(size = degree), colour = "steelblue") + -#' geom_nodelabel(aes(label = vertex.names), data = high_degree, -#' colour = "white", fill = "tomato") + -#' theme_blank() +#' # label only a subset of all nodes +#' high_degree <- function(x) { +#' x[ x$degree > median(x$degree), ] +#' } +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(colour = "steelblue") + +#' geom_nodes(aes(size = degree), colour = "steelblue") + +#' geom_nodelabel(aes(label = vertex.names), +#' data = high_degree, +#' colour = "white", fill = "tomato" +#' ) + +#' theme_blank() #' } -#' #' @export geom_nodelabel <- function(mapping = NULL, data = NULL, position = "identity", @@ -291,52 +282,53 @@ geom_nodelabel <- function(mapping = NULL, data = NULL, #' ## geom_nodelabel_repel examples #' #' if (require(network) && require(sna)) { +#' data(flo, package = "network") +#' n <- network(flo, directed = FALSE) #' -#' data(flo, package = "network") -#' n <- network(flo, directed = FALSE) -#' -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(colour = "steelblue") + -#' geom_nodelabel_repel(aes(label = vertex.names), -#' box.padding = unit(1, "lines")) + -#' geom_nodes(colour = "steelblue", size = 3) + -#' theme_blank() -#' -#' # label only a subset of all nodes -#' n %v% "degree" <- degree(n) -#' low_degree <- function(x) { x[ x$degree < median(x$degree), ] } -#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + -#' geom_edges(colour = "steelblue") + -#' geom_nodelabel_repel(aes(label = vertex.names), -#' box.padding = unit(1.5, "lines"), -#' data = low_degree, -#' segment.colour = "tomato", -#' colour = "white", fill = "tomato") + -#' geom_nodes(aes(size = degree), colour = "steelblue") + -#' theme_blank() +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(colour = "steelblue") + +#' geom_nodelabel_repel(aes(label = vertex.names), +#' box.padding = unit(1, "lines") +#' ) + +#' geom_nodes(colour = "steelblue", size = 3) + +#' theme_blank() #' +#' # label only a subset of all nodes +#' n %v% "degree" <- degree(n) +#' low_degree <- function(x) { +#' x[ x$degree < median(x$degree), ] +#' } +#' ggplot(n, aes(x, y, xend = xend, yend = yend)) + +#' geom_edges(colour = "steelblue") + +#' geom_nodelabel_repel(aes(label = vertex.names), +#' box.padding = unit(1.5, "lines"), +#' data = low_degree, +#' segment.colour = "tomato", +#' colour = "white", fill = "tomato" +#' ) + +#' geom_nodes(aes(size = degree), colour = "steelblue") + +#' theme_blank() #' } #' @export geom_nodelabel_repel <- function( - mapping = NULL, data = NULL, - parse = FALSE, - ..., - box.padding = unit(0.25, "lines"), - label.padding = unit(0.25, "lines"), - point.padding = unit(1e-6, "lines"), - label.r = unit(0.15, "lines"), - label.size = 0.25, - segment.colour = "#666666", - segment.size = 0.5, - arrow = NULL, - force = 1, - max.iter = 2000, - nudge_x = 0, - nudge_y = 0, - na.rm = FALSE, - show.legend = NA, - inherit.aes = TRUE -) { + mapping = NULL, data = NULL, + parse = FALSE, + ..., + box.padding = unit(0.25, "lines"), + label.padding = unit(0.25, "lines"), + point.padding = unit(1e-6, "lines"), + label.r = unit(0.15, "lines"), + label.size = 0.25, + segment.colour = "#666666", + segment.size = 0.5, + arrow = NULL, + force = 1, + max.iter = 2000, + nudge_x = 0, + nudge_y = 0, + na.rm = FALSE, + show.legend = NA, + inherit.aes = TRUE) { layer( data = data, mapping = mapping, @@ -347,9 +339,9 @@ geom_nodelabel_repel <- function( inherit.aes = inherit.aes, params = list( parse = parse, - box.padding = box.padding, + box.padding = box.padding, label.padding = label.padding, - point.padding = point.padding, + point.padding = point.padding, label.r = label.r, label.size = label.size, segment.colour = segment.colour, @@ -369,11 +361,11 @@ geom_nodelabel_repel <- function( #' @keywords internal StatNodes <- ggplot2::ggproto("StatNodes", ggplot2::Stat, - compute_layer = function(data, scales, params) { - if (all(c("xend", "yend") %in% names(data))) { - unique(subset(data, select = c(-xend, -yend))) - } else { - unique(data) - } - } + compute_layer = function(data, scales, params) { + if (all(c("xend", "yend") %in% names(data))) { + unique(subset(data, select = c(-xend, -yend))) + } else { + unique(data) + } + } ) diff --git a/R/ggnetwork.R b/R/ggnetwork.R index 169102d..6a2b9ca 100644 --- a/R/ggnetwork.R +++ b/R/ggnetwork.R @@ -14,29 +14,17 @@ #' @param ... arguments passed to the \code{\link{fortify.network}} function. #' @export ggnetwork <- function(x, ...) { - if (class(x) == "igraph") { - fortify.igraph(x, ...) - } else { - if (!network::is.network(x)) { - - x = try(network::network(x), silent = TRUE) - + x <- try(network::network(x), silent = TRUE) } if (!network::is.network(x)) { - stop("could not coerce object to a network") - } else { - fortify.network(x, ...) - } - } - } diff --git a/R/utilities.R b/R/utilities.R index 2cb96da..f36c4fe 100644 --- a/R/utilities.R +++ b/R/utilities.R @@ -37,7 +37,7 @@ theme_facet <- function(base_size = 12, base_family = "", ...) { } #' Rescale x to (0, 1), except if x is constant -#' +#' #' Discussed in PR #32: https://github.com/briatte/ggnetwork/pull/32 #' @param x a vector to rescale #' @param scale the scale on which to rescale the vector diff --git a/tests/testthat/test-fortify.R b/tests/testthat/test-fortify.R index 456711c..b3cba8f 100644 --- a/tests/testthat/test-fortify.R +++ b/tests/testthat/test-fortify.R @@ -6,7 +6,6 @@ library(network) library(sna) test_that("fortify.network works", { - n <- network(flo, directed = FALSE) expect_is(fortify(n), "data.frame") @@ -18,11 +17,9 @@ test_that("fortify.network works", { geom_nodetext(aes(label = vertex.names)) + geom_edgetext(aes(label = 1)) + theme_blank() - }) test_that("fortify.igraph works", { - n <- igraph::graph_from_adjacency_matrix(flo, mode = "undirected") expect_is(fortify(n), "data.frame") @@ -34,5 +31,4 @@ test_that("fortify.igraph works", { geom_nodetext(aes(label = vertex.names)) + geom_edgetext(aes(label = 1)) + theme_blank() - }) diff --git a/tests/testthat/test-geoms.R b/tests/testthat/test-geoms.R index 137454e..459134b 100644 --- a/tests/testthat/test-geoms.R +++ b/tests/testthat/test-geoms.R @@ -3,17 +3,14 @@ context("Test all geoms") data(emon, package = "network") test_that("geom_nodes works", { - ggplot(emon[[1]], aes(x, y)) + geom_nodes() ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + geom_nodes() - }) test_that("geom_nodetext works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + geom_nodetext(aes(label = vertex.names)) @@ -22,22 +19,20 @@ test_that("geom_nodetext works", { expect_error( ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_nodetext(aes(label = Paid.Staff), nudge_x = 1, nudge_y = 1, - position = "identity"), + geom_nodetext(aes(label = Paid.Staff), + nudge_x = 1, nudge_y = 1, + position = "identity" + ), "Specify either" ) - }) test_that("geom_nodetext_repel works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + geom_nodetext_repel(aes(label = vertex.names)) - }) test_that("geom_nodelabel works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + geom_nodelabel(aes(label = vertex.names)) @@ -46,18 +41,17 @@ test_that("geom_nodelabel works", { expect_error( ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_nodelabel(aes(label = Paid.Staff), nudge_x = 1, nudge_y = 1, - position = "identity"), + geom_nodelabel(aes(label = Paid.Staff), + nudge_x = 1, nudge_y = 1, + position = "identity" + ), "Specify either" ) - }) test_that("geom_nodelabel_repel works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + geom_nodelabel_repel(aes(label = vertex.names)) - }) test_that("geom_edges works", { @@ -69,11 +63,9 @@ test_that("geom_edges works", { # curved ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + geom_edges(curvature = 0.1) - }) test_that("geom_edgetext works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + geom_edgetext(aes(label = Frequency)) @@ -82,30 +74,25 @@ test_that("geom_edgetext works", { expect_error( ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_edgetext(aes(label = Frequency), nudge_x = 1, nudge_y = 1, - position = "identity"), + geom_edgetext(aes(label = Frequency), + nudge_x = 1, nudge_y = 1, + position = "identity" + ), "Specify either" ) - }) test_that("geom_edgelabel works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + geom_edgelabel(aes(label = Frequency)) - }) test_that("geom_edgetext_repel works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + geom_edgetext_repel(aes(label = Frequency)) - }) test_that("geom_edgelabel_repel works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + geom_edgelabel_repel(aes(label = Frequency)) - -}) \ No newline at end of file +}) diff --git a/tests/testthat/test-ggnetwork.R b/tests/testthat/test-ggnetwork.R index 9569a92..4e37c46 100644 --- a/tests/testthat/test-ggnetwork.R +++ b/tests/testthat/test-ggnetwork.R @@ -3,7 +3,6 @@ context("Test ggnetwork") data(emon, package = "network") test_that("ggnetwork works", { - expect_error(ggnetwork(-999, "could not coerce")) expect_error(ggnetwork(emon[[1]], layout = -999, "unsupported layout")) @@ -20,8 +19,8 @@ test_that("ggnetwork works", { expect_warning( ggnetwork(rbind( matrix(c(1:2, 2:1), nrow = 2), - matrix(c(1:2, 2:1), nrow = 2))), + matrix(c(1:2, 2:1), nrow = 2) + )), "duplicated edges" ) - }) diff --git a/tests/testthat/test-utilities.R b/tests/testthat/test-utilities.R index 9fb00fd..f6c92b2 100644 --- a/tests/testthat/test-utilities.R +++ b/tests/testthat/test-utilities.R @@ -1,19 +1,15 @@ context("Test utilities") test_that("theme_blank works", { - ggplot(ggnetwork(emon[[1]]), aes(x, y, xend = xend, yend = yend)) + geom_edges() + geom_nodes() + theme_blank() - }) test_that("theme_facet works", { - ggplot(ggnetwork(emon[[1]]), aes(x, y, xend = xend, yend = yend)) + geom_edges() + geom_nodes() + theme_facet() - }) From d4513f6ef7bc68bf10c7a296852bf18ff6f6e455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 16:34:37 +0200 Subject: [PATCH 16/48] set development version 0.5.6.9000 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 00da44e..18f2c74 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: ggnetwork Type: Package Title: Geometries to Plot Networks with 'ggplot2' -Version: 0.5.4 +Version: 0.5.6.9000 Date: 2016-03-24 Maintainer: François Briatte Authors@R: c( From f5a98d1314ac0bdc342c6398fdb392bf5787b913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 16:34:55 +0200 Subject: [PATCH 17/48] add changelog for 0.5.6 --- NEWS.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/NEWS.md b/NEWS.md index 57727bd..d2417b2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,31 @@ +# ggnetwork 0.5.6 + +## Repository changes + +* Add `README.Rmd` (replace `README.md`), + + use badges. + + list all GitHub contributors. + + add Contributing, Code of Conduct Issue Template and Support markdown file (`usethis`). + +* Improve `.travis.yml`, + + use `pkgdown` for website deployment. + - add `_pkgdown.yml` configuration file. + + use `covr` for code coverage. + - add default `codecov.yml` configuration file. + +* Add `ggnetwork.Rproj`, for ease of use within Rstudio. + +## Minor improvements and fixes + +* In `DESCRIPTION`, + + update RoxygenNote version. + + Remove `ggplot2` from `Enhances` field. + +* Remove `inst/doc/` directory, *i.e.*, the vignette is part of the `pkgdown` website. + +* Use tidy code style. + + ggnetwork 0.5.4 (2017-07-XX) ---------------------------- From 0a42a7685138eda302af4f35c5c1e1adf65c3f6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 16:35:06 +0200 Subject: [PATCH 18/48] update roxygen doc --- man/fortify.network.Rd | 34 +++++++---- man/geom_edges.Rd | 119 ++++++++++++++++++++----------------- man/geom_edgetext.Rd | 46 +++++++------- man/geom_edgetext_repel.Rd | 56 +++++++++-------- man/geom_nodes.Rd | 60 +++++++++---------- man/geom_nodetext.Rd | 96 +++++++++++++++--------------- man/geom_nodetext_repel.Rd | 67 +++++++++++---------- 7 files changed, 250 insertions(+), 228 deletions(-) diff --git a/man/fortify.network.Rd b/man/fortify.network.Rd index 23f703d..ebf21d9 100644 --- a/man/fortify.network.Rd +++ b/man/fortify.network.Rd @@ -80,39 +80,49 @@ if (require(ggplot2) && require(network)) { ggnetwork(emon[[1]], layout = "kamadakawai", weights = "Frequency") # plot example with straight edges - ggplot(ggnetwork(emon[[1]], layout = "kamadakawai", arrow.gap = 0.025), - aes(x, y, xend = xend, yend = yend)) + + ggplot( + ggnetwork(emon[[1]], layout = "kamadakawai", arrow.gap = 0.025), + aes(x, y, xend = xend, yend = yend) + ) + geom_edges(aes(color = Frequency), - arrow = arrow(length = unit(10, "pt"), type = "closed")) + + arrow = arrow(length = unit(10, "pt"), type = "closed") + ) + geom_nodes(aes(size = Formalization)) + scale_color_gradient(low = "grey50", high = "tomato") + scale_size_area(breaks = 1:3) + theme_blank() # plot example with curved edges - ggplot(ggnetwork(emon[[1]], layout = "kamadakawai", arrow.gap = 0.025), - aes(x, y, xend = xend, yend = yend)) + - geom_edges(aes(color = Frequency), curvature = 0.1, - arrow = arrow(length = unit(10, "pt"), type = "open")) + + ggplot( + ggnetwork(emon[[1]], layout = "kamadakawai", arrow.gap = 0.025), + aes(x, y, xend = xend, yend = yend) + ) + + geom_edges(aes(color = Frequency), + curvature = 0.1, + arrow = arrow(length = unit(10, "pt"), type = "open") + ) + geom_nodes(aes(size = Formalization)) + scale_color_gradient(low = "grey50", high = "tomato") + scale_size_area(breaks = 1:3) + theme_blank() # facet by edge attribute - ggplot(ggnetwork(emon[[1]], arrow.gap = 0.02, by = "Frequency"), - aes(x, y, xend = xend, yend = yend)) + + ggplot( + ggnetwork(emon[[1]], arrow.gap = 0.02, by = "Frequency"), + aes(x, y, xend = xend, yend = yend) + ) + geom_edges(arrow = arrow(length = unit(5, "pt"), type = "closed")) + geom_nodes() + theme_blank() + facet_grid(. ~ Frequency, labeller = label_both) # user-provided layout - ggplot(ggnetwork(emon[[1]], layout = matrix(runif(28), ncol = 2)), - aes(x, y, xend = xend, yend = yend)) + + ggplot( + ggnetwork(emon[[1]], layout = matrix(runif(28), ncol = 2)), + aes(x, y, xend = xend, yend = yend) + ) + geom_edges(arrow = arrow(length = unit(5, "pt"), type = "closed")) + geom_nodes() + theme_blank() - } } diff --git a/man/geom_edges.Rd b/man/geom_edges.Rd index fc4c5c8..9d28ad4 100644 --- a/man/geom_edges.Rd +++ b/man/geom_edges.Rd @@ -78,60 +78,69 @@ edges produced by \code{geom_edges} will be curved. \examples{ if (require(network) && require(sna)) { -# rerun if the example does not produce reciprocated ties -n <- network(rgraph(10, tprob = 0.2), directed = TRUE) - -# just edges -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(size = 1, colour = "steelblue") + - theme_blank() - -# with nodes -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(size = 1, colour = "steelblue") + - geom_nodes(size = 3, colour = "steelblue") + - theme_blank() - -# with arrows -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(size = 1, colour = "steelblue", - arrow = arrow(length = unit(0.5, "lines"), type = "closed")) + - geom_nodes(size = 3, colour = "steelblue") + - theme_blank() - -# with curvature -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(size = 1, colour = "steelblue", curvature = 0.15, - arrow = arrow(length = unit(0.5, "lines"), type = "closed")) + - geom_nodes(size = 3, colour = "steelblue") + - theme_blank() - -# arbitrary categorical edge attribute -e <- sample(letters[ 1:2 ], network.edgecount(n), replace = TRUE) -set.edge.attribute(n, "type", e) -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(aes(linetype = type), size = 1, curvature = 0.15, - arrow = arrow(length = unit(0.5, "lines"), type = "closed")) + - geom_nodes(size = 3, colour = "steelblue") + - theme_blank() - -# arbitrary numeric edge attribute (signed network) -e <- sample(-2:2, network.edgecount(n), replace = TRUE) -set.edge.attribute(n, "weight", e) -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(aes(colour = weight), curvature = 0.15, - arrow = arrow(length = unit(0.5, "lines"), type = "closed")) + - geom_nodes(size = 3, colour = "grey50") + - scale_colour_gradient(low = "steelblue", high = "tomato") + - theme_blank() - -# draw only a subset of all edges -positive_weight <- function(x) { x[ x$weight >= 0, ] } -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(aes(colour = weight), data = positive_weight) + - geom_nodes(size = 4, colour = "grey50") + - scale_colour_gradient(low = "gold", high = "tomato") + - theme_blank() - + # rerun if the example does not produce reciprocated ties + n <- network(rgraph(10, tprob = 0.2), directed = TRUE) + + # just edges + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(size = 1, colour = "steelblue") + + theme_blank() + + # with nodes + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(size = 1, colour = "steelblue") + + geom_nodes(size = 3, colour = "steelblue") + + theme_blank() + + # with arrows + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges( + size = 1, colour = "steelblue", + arrow = arrow(length = unit(0.5, "lines"), type = "closed") + ) + + geom_nodes(size = 3, colour = "steelblue") + + theme_blank() + + # with curvature + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges( + size = 1, colour = "steelblue", curvature = 0.15, + arrow = arrow(length = unit(0.5, "lines"), type = "closed") + ) + + geom_nodes(size = 3, colour = "steelblue") + + theme_blank() + + # arbitrary categorical edge attribute + e <- sample(letters[ 1:2 ], network.edgecount(n), replace = TRUE) + set.edge.attribute(n, "type", e) + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(aes(linetype = type), + size = 1, curvature = 0.15, + arrow = arrow(length = unit(0.5, "lines"), type = "closed") + ) + + geom_nodes(size = 3, colour = "steelblue") + + theme_blank() + + # arbitrary numeric edge attribute (signed network) + e <- sample(-2:2, network.edgecount(n), replace = TRUE) + set.edge.attribute(n, "weight", e) + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(aes(colour = weight), + curvature = 0.15, + arrow = arrow(length = unit(0.5, "lines"), type = "closed") + ) + + geom_nodes(size = 3, colour = "grey50") + + scale_colour_gradient(low = "steelblue", high = "tomato") + + theme_blank() + + # draw only a subset of all edges + positive_weight <- function(x) { + x[ x$weight >= 0, ] + } + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(aes(colour = weight), data = positive_weight) + + geom_nodes(size = 4, colour = "grey50") + + scale_colour_gradient(low = "gold", high = "tomato") + + theme_blank() } } diff --git a/man/geom_edgetext.Rd b/man/geom_edgetext.Rd index b183729..f07782b 100644 --- a/man/geom_edgetext.Rd +++ b/man/geom_edgetext.Rd @@ -83,28 +83,28 @@ identical results. } \examples{ if (require(network) && require(sna)) { - -data(flo, package = "network") -n <- network(flo, directed = FALSE) - -# arbitrary categorical edge attribute -e <- sample(letters[ 1:4 ], network.edgecount(n), replace = TRUE) -set.edge.attribute(n, "type", e) - -# with labelled edges -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(aes(colour = type)) + - geom_edgetext(aes(label = type, colour = type)) + - geom_nodes(size = 4, colour = "grey50") + - theme_blank() - -# label only a subset of all edges with arbitrary symbol -edge_type <- function(x) { x[ x$type == "a", ] } -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges() + - geom_edgetext(label = "=", data = edge_type) + - geom_nodes(size = 4, colour = "grey50") + - theme_blank() - + data(flo, package = "network") + n <- network(flo, directed = FALSE) + + # arbitrary categorical edge attribute + e <- sample(letters[ 1:4 ], network.edgecount(n), replace = TRUE) + set.edge.attribute(n, "type", e) + + # with labelled edges + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(aes(colour = type)) + + geom_edgetext(aes(label = type, colour = type)) + + geom_nodes(size = 4, colour = "grey50") + + theme_blank() + + # label only a subset of all edges with arbitrary symbol + edge_type <- function(x) { + x[ x$type == "a", ] + } + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges() + + geom_edgetext(label = "=", data = edge_type) + + geom_nodes(size = 4, colour = "grey50") + + theme_blank() } } diff --git a/man/geom_edgetext_repel.Rd b/man/geom_edgetext_repel.Rd index 68de4e3..0843f0e 100644 --- a/man/geom_edgetext_repel.Rd +++ b/man/geom_edgetext_repel.Rd @@ -101,31 +101,35 @@ All arguments to both \code{\link{geom_edgetext_repel}} and } \examples{ if (require(network) && require(sna)) { - -data(flo, package = "network") -n <- network(flo, directed = FALSE) - -# arbitrary categorical edge attribute -e <- sample(1:4, network.edgecount(n), replace = TRUE) -set.edge.attribute(n, "day", e) - -# with repulsive edge labels -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges() + - geom_edgetext_repel(aes(label = day), box.padding = unit(0.5, "lines")) + - geom_nodes(size = 4, colour = "grey50") + - theme_blank() - -# repulsive edge labels for only a subset of all edges -edge_day <- function(x) { x[ x$day > 2, ] } -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(aes(colour = cut(day, (4:0)[ -3 ]))) + - geom_edgetext_repel(aes(label = paste("day", day), - colour = cut(day, (4:0)[ -3 ])), data = edge_day) + - geom_nodes(size = 4, colour = "grey50") + - scale_colour_manual("day", labels = c("old ties", "day 3", "day 4"), - values = c("grey50", "gold", "tomato")) + - theme_blank() - + data(flo, package = "network") + n <- network(flo, directed = FALSE) + + # arbitrary categorical edge attribute + e <- sample(1:4, network.edgecount(n), replace = TRUE) + set.edge.attribute(n, "day", e) + + # with repulsive edge labels + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges() + + geom_edgetext_repel(aes(label = day), box.padding = unit(0.5, "lines")) + + geom_nodes(size = 4, colour = "grey50") + + theme_blank() + + # repulsive edge labels for only a subset of all edges + edge_day <- function(x) { + x[ x$day > 2, ] + } + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(aes(colour = cut(day, (4:0)[ -3 ]))) + + geom_edgetext_repel(aes( + label = paste("day", day), + colour = cut(day, (4:0)[ -3 ]) + ), data = edge_day) + + geom_nodes(size = 4, colour = "grey50") + + scale_colour_manual("day", + labels = c("old ties", "day 3", "day 4"), + values = c("grey50", "gold", "tomato") + ) + + theme_blank() } } diff --git a/man/geom_nodes.Rd b/man/geom_nodes.Rd index 0c4e0b7..28e3c5b 100644 --- a/man/geom_nodes.Rd +++ b/man/geom_nodes.Rd @@ -56,36 +56,34 @@ All arguments to this geom are identical to those of } \examples{ if (require(network) && require(sna)) { - -data(flo, package = "network") -n <- network(flo, directed = FALSE) - -# just nodes -ggplot(n, aes(x, y)) + - geom_nodes(size = 3, shape = 21, colour = "steelblue") + - theme_blank() - -# with edges -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(colour = "steelblue") + - geom_nodes(size = 3, shape = 21, colour = "steelblue", fill = "white") + - theme_blank() - -# with nodes sized according to degree centrality -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(colour = "steelblue") + - geom_nodes(size = degree(n), shape = 21, colour = "steelblue", fill = "white") + - theme_blank() - -# with nodes colored according to betweenness centrality - -n \%v\% "betweenness" <- betweenness(flo) -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(colour = "grey50") + - geom_nodes(aes(colour = betweenness), size = 3) + - scale_colour_gradient(low = "gold", high = "tomato") + - theme_blank() + - theme(legend.position = "bottom") - + data(flo, package = "network") + n <- network(flo, directed = FALSE) + + # just nodes + ggplot(n, aes(x, y)) + + geom_nodes(size = 3, shape = 21, colour = "steelblue") + + theme_blank() + + # with edges + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(colour = "steelblue") + + geom_nodes(size = 3, shape = 21, colour = "steelblue", fill = "white") + + theme_blank() + + # with nodes sized according to degree centrality + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(colour = "steelblue") + + geom_nodes(size = degree(n), shape = 21, colour = "steelblue", fill = "white") + + theme_blank() + + # with nodes colored according to betweenness centrality + + n \%v\% "betweenness" <- betweenness(flo) + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(colour = "grey50") + + geom_nodes(aes(colour = betweenness), size = 3) + + scale_colour_gradient(low = "gold", high = "tomato") + + theme_blank() + + theme(legend.position = "bottom") } } diff --git a/man/geom_nodetext.Rd b/man/geom_nodetext.Rd index 01e2bec..f690b7b 100644 --- a/man/geom_nodetext.Rd +++ b/man/geom_nodetext.Rd @@ -82,58 +82,58 @@ All arguments to these geoms are identical to those of ## geom_nodetext examples if (require(network) && require(sna)) { - -n <- network(rgraph(10, tprob = 0.2), directed = FALSE) - -# just node labels -ggplot(n, aes(x, y)) + - geom_nodetext(aes(label = vertex.names)) + - theme_blank() - -# with nodes underneath -ggplot(n, aes(x, y)) + - geom_nodes(colour = "gold", size = 9) + - geom_nodetext(aes(label = vertex.names)) + - theme_blank() - -# with nodes and edges -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(colour = "gold") + - geom_nodes(colour = "gold", size = 9) + - geom_nodetext(aes(label = vertex.names)) + - theme_blank() - + n <- network(rgraph(10, tprob = 0.2), directed = FALSE) + + # just node labels + ggplot(n, aes(x, y)) + + geom_nodetext(aes(label = vertex.names)) + + theme_blank() + + # with nodes underneath + ggplot(n, aes(x, y)) + + geom_nodes(colour = "gold", size = 9) + + geom_nodetext(aes(label = vertex.names)) + + theme_blank() + + # with nodes and edges + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(colour = "gold") + + geom_nodes(colour = "gold", size = 9) + + geom_nodetext(aes(label = vertex.names)) + + theme_blank() } ## geom_nodelabel examples if (require(network) && require(sna)) { - -data(flo, package = "network") -n <- network(flo, directed = FALSE) - -# with text labels -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(colour = "grey50") + - geom_nodelabel(aes(label = vertex.names)) + - theme_blank() - -# with text labels coloured according to degree centrality -n \%v\% "degree" <- degree(n) -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(colour = "grey50") + - geom_nodelabel(aes(label = vertex.names, fill = degree)) + - scale_fill_gradient(low = "gold", high = "tomato") + - theme_blank() - -# label only a subset of all nodes -high_degree <- function(x) { x[ x$degree > median(x$degree), ] } -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(colour = "steelblue") + - geom_nodes(aes(size = degree), colour = "steelblue") + - geom_nodelabel(aes(label = vertex.names), data = high_degree, - colour = "white", fill = "tomato") + - theme_blank() + data(flo, package = "network") + n <- network(flo, directed = FALSE) + + # with text labels + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(colour = "grey50") + + geom_nodelabel(aes(label = vertex.names)) + + theme_blank() + + # with text labels coloured according to degree centrality + n \%v\% "degree" <- degree(n) + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(colour = "grey50") + + geom_nodelabel(aes(label = vertex.names, fill = degree)) + + scale_fill_gradient(low = "gold", high = "tomato") + + theme_blank() + + # label only a subset of all nodes + high_degree <- function(x) { + x[ x$degree > median(x$degree), ] + } + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(colour = "steelblue") + + geom_nodes(aes(size = degree), colour = "steelblue") + + geom_nodelabel(aes(label = vertex.names), + data = high_degree, + colour = "white", fill = "tomato" + ) + + theme_blank() } - } diff --git a/man/geom_nodetext_repel.Rd b/man/geom_nodetext_repel.Rd index f36c5ab..319674a 100644 --- a/man/geom_nodetext_repel.Rd +++ b/man/geom_nodetext_repel.Rd @@ -100,42 +100,43 @@ All arguments to these geoms are identical to those of ## geom_nodetext_repel example if (require(network) && require(sna)) { - -n <- network(rgraph(10, tprob = 0.2), directed = FALSE) -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(colour = "steelblue") + - geom_nodetext_repel(aes(label = paste("node", vertex.names)), - box.padding = unit(1, "lines")) + - geom_nodes(colour = "steelblue", size = 3) + - theme_blank() - + n <- network(rgraph(10, tprob = 0.2), directed = FALSE) + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(colour = "steelblue") + + geom_nodetext_repel(aes(label = paste("node", vertex.names)), + box.padding = unit(1, "lines") + ) + + geom_nodes(colour = "steelblue", size = 3) + + theme_blank() } ## geom_nodelabel_repel examples if (require(network) && require(sna)) { - -data(flo, package = "network") -n <- network(flo, directed = FALSE) - -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(colour = "steelblue") + - geom_nodelabel_repel(aes(label = vertex.names), - box.padding = unit(1, "lines")) + - geom_nodes(colour = "steelblue", size = 3) + - theme_blank() - -# label only a subset of all nodes -n \%v\% "degree" <- degree(n) -low_degree <- function(x) { x[ x$degree < median(x$degree), ] } -ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges(colour = "steelblue") + - geom_nodelabel_repel(aes(label = vertex.names), - box.padding = unit(1.5, "lines"), - data = low_degree, - segment.colour = "tomato", - colour = "white", fill = "tomato") + - geom_nodes(aes(size = degree), colour = "steelblue") + - theme_blank() - + data(flo, package = "network") + n <- network(flo, directed = FALSE) + + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(colour = "steelblue") + + geom_nodelabel_repel(aes(label = vertex.names), + box.padding = unit(1, "lines") + ) + + geom_nodes(colour = "steelblue", size = 3) + + theme_blank() + + # label only a subset of all nodes + n \%v\% "degree" <- degree(n) + low_degree <- function(x) { + x[ x$degree < median(x$degree), ] + } + ggplot(n, aes(x, y, xend = xend, yend = yend)) + + geom_edges(colour = "steelblue") + + geom_nodelabel_repel(aes(label = vertex.names), + box.padding = unit(1.5, "lines"), + data = low_degree, + segment.colour = "tomato", + colour = "white", fill = "tomato" + ) + + geom_nodes(aes(size = degree), colour = "steelblue") + + theme_blank() } } From 6e2f82dbf87ffdca2675b92d3abd92a657c88ef9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 16:41:22 +0200 Subject: [PATCH 19/48] restyle a bit the NEWS --- NEWS.md | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/NEWS.md b/NEWS.md index d2417b2..9c10824 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,5 @@ -# ggnetwork 0.5.6 +ggnetwork 0.5.6 +============================ ## Repository changes @@ -24,22 +25,28 @@ * Remove `inst/doc/` directory, *i.e.*, the vignette is part of the `pkgdown` website. * Use tidy code style. + + +ggnetwork 0.5.5 (2017-08-XX) +============================ ggnetwork 0.5.4 (2017-07-XX) ----------------------------- +============================ -Changes +## Minor improvements and fixes * Added native support for igraph. Thanks to [Jake Fisher](www.src.isr.umich.edu/people/jake-fisher/). ggnetwork 0.5.3 (2016-06-XX) ----------------------------- +============================ -Added Travis CI. +## Repository changes -FIXES +* Added Travis CI. + +## Minor improvements and fixes * Export ggplot2::Stat to enable loading ggnetwork first (#14). Thanks to Tyler Rinker. @@ -47,23 +54,22 @@ FIXES * Safer calls to the sna package (#9). Thanks to Michał Bojanowski. + ggnetwork 0.5.2 (2016-05-01) ----------------------------- +============================ -FIXES +## Minor improvements and fixes * Fixed a bug that removed labels from strictly vertical or strictly horizontal edges (#5). * Fixed a small documentation issue that was corrected in roxygen 5.0.2 (#4). -CHANGES - * Support for segment colors in all geoms using ggrepel 0.5.1 (#3). * Added some acknowledgements to the README and links to the DESCRIPTION. ggnetwork 0.5.1 (2016-03-25) ----------------------------- +============================ First CRAN release. From c1ec58007576705da3bbe2dce1efe666486da3e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 16:44:45 +0200 Subject: [PATCH 20/48] minor style changes --- R/fortify-igraph.R | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/R/fortify-igraph.R b/R/fortify-igraph.R index 6d7f91c..9cdaa3d 100644 --- a/R/fortify-igraph.R +++ b/R/fortify-igraph.R @@ -25,9 +25,11 @@ fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), x <- model # node placement - if (class(layout) == "matrix" && - nrow(layout) == igraph::gorder(x) && - ncol(layout) == 2) { + if ( + class(layout) == "matrix" && + nrow(layout) == igraph::gorder(x) && + ncol(layout) == 2 + ) { nodes <- layout[, 1:2 ] } else { nodes <- igraph::layout_(x, layout, ...) @@ -35,7 +37,7 @@ fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), # store coordinates nodes <- data.frame(nodes) - names(nodes) <- c("x", "y") + colnames(nodes) <- c("x", "y") # rescale coordinates nodes$x <- scale_safely(nodes$x) @@ -49,14 +51,14 @@ fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), igraph::list.vertex.attributes(x), FUN = igraph::get.vertex.attribute, graph = x, - USE.NAMES = T + USE.NAMES = TRUE ) ) } # edge list - edges <- igraph::as_edgelist(x, names = F) + edges <- igraph::as_edgelist(x, names = FALSE) # edge list (if there are duplicated rows) if (nrow(edges[, 1:2]) > nrow(unique(edges[, 1:2]))) { From 01cc1946c2aee5813fc740fa691820f9f47f64d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 16:47:35 +0200 Subject: [PATCH 21/48] replace "with" and "transform" by subsetting methods (i.e., not intended to be used in programming) --- R/fortify-igraph.R | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/R/fortify-igraph.R b/R/fortify-igraph.R index 9cdaa3d..523f443 100644 --- a/R/fortify-igraph.R +++ b/R/fortify-igraph.R @@ -72,14 +72,9 @@ fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), if (arrow.gap > 0) { x.length <- edges$xend - edges$x y.length <- edges$yend - edges$y - arrow.gap <- with(edges, arrow.gap / sqrt(x.length^2 + y.length^2)) - edges <- transform( - edges, - # x = x + arrow.gap * x.length, - # y = y + arrow.gap * y.length, - xend = x + (1 - arrow.gap) * x.length, - yend = y + (1 - arrow.gap) * y.length - ) + arrow.gap <- edges$arrow.gap / sqrt(x.length^2 + y.length^2) + edges$xend <- edges$x + (1 - arrow.gap) * x.length + edges$yend <- edges$y + (1 - arrow.gap) * y.length } # import edge attributes From c4787a4a4b0c1996e1a25cc82d24380959f520e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 16:50:32 +0200 Subject: [PATCH 22/48] full "TRUE" --- R/fortify-igraph.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/fortify-igraph.R b/R/fortify-igraph.R index 523f443..52f53e4 100644 --- a/R/fortify-igraph.R +++ b/R/fortify-igraph.R @@ -85,7 +85,7 @@ fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), igraph::list.edge.attributes(x), FUN = igraph::get.edge.attribute, graph = x, - USE.NAMES = T + USE.NAMES = TRUE ) ) } From ad3bf757f8981877d95fa0b7eefba7f5b49f5a64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 16:54:02 +0200 Subject: [PATCH 23/48] use subsetting functions instead of `with` and `transform` --- R/fortify-network.R | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/R/fortify-network.R b/R/fortify-network.R index 13b3abe..af5bdd0 100644 --- a/R/fortify-network.R +++ b/R/fortify-network.R @@ -118,9 +118,11 @@ fortify.network <- function(model, data = NULL, x <- model # node placement - if (class(layout) == "matrix" && - nrow(layout) == network::network.size(x) && - ncol(layout) == 2) { + if ( + class(layout) == "matrix" && + nrow(layout) == network::network.size(x) && + ncol(layout) == 2 + ) { nodes <- layout[, 1:2 ] } else { layout <- paste0("gplot.layout.", layout) @@ -158,16 +160,11 @@ fortify.network <- function(model, data = NULL, # arrow gap (thanks to @heike and @ethen8181 for their work on this issue) if (arrow.gap > 0) { - x.length <- with(edges, xend - x) - y.length <- with(edges, yend - y) - arrow.gap <- with(edges, arrow.gap / sqrt(x.length^2 + y.length^2)) - edges <- transform( - edges, - # x = x + arrow.gap * x.length, - # y = y + arrow.gap * y.length, - xend = x + (1 - arrow.gap) * x.length, - yend = y + (1 - arrow.gap) * y.length - ) + x.length <- edges$xend - edges$x + y.length <- edges$yend - edges$y + arrow.gap <- edges$arrow.gap / sqrt(x.length^2 + y.length^2) + edges$xend <- edges$x + (1 - arrow.gap) * x.length + edges$yend <- edges$y + (1 - arrow.gap) * y.length } # import edge attributes From 620ad8ffd6a06f5ac83b6aac22a63da5dae14c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 17:16:02 +0200 Subject: [PATCH 24/48] use remotes instead of devtools --- vignettes/ggnetwork.Rmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vignettes/ggnetwork.Rmd b/vignettes/ggnetwork.Rmd index 0501193..4874f63 100644 --- a/vignettes/ggnetwork.Rmd +++ b/vignettes/ggnetwork.Rmd @@ -25,10 +25,10 @@ Install the stable version from CRAN: install.packages("ggnetwork") ``` -Or use `devtools` to install the latest version of the package [from GitHub](https://github.com/briatte/ggnetwork): +Or use `remotes` to install the latest version of the package [from GitHub](https://github.com/briatte/ggnetwork): ```{r, eval=FALSE} -devtools::install_github("briatte/ggnetwork") +remotes::install_github("briatte/ggnetwork") ``` The package is meant to be used with `ggplot2` version 2.0.0 or above, so make sure that you update your version of `ggplot2` from CRAN before using `ggnetwork`: From 4841eebd4f7affa68218cda1cfc62bfa7cc6cf0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 17:16:33 +0200 Subject: [PATCH 25/48] global variable leading to unintended behaviour ... --- NEWS.md | 5 +++++ R/fortify-igraph.R | 43 ++++++++++++++++++++++++------------------- R/fortify-network.R | 43 ++++++++++++++++++++++--------------------- 3 files changed, 51 insertions(+), 40 deletions(-) diff --git a/NEWS.md b/NEWS.md index 9c10824..433eef4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -26,6 +26,11 @@ ggnetwork 0.5.6 * Use tidy code style. +* In `R/fortify-igraph.R` and `R/fortify-network.R`, + + use subsetting functions instead of `with` and `transform` (*i.e.*, intended to be use interactively). + + fix issue from CRAN check with undefined global variables. + + ggnetwork 0.5.5 (2017-08-XX) ============================ diff --git a/R/fortify-igraph.R b/R/fortify-igraph.R index 52f53e4..cba1203 100644 --- a/R/fortify-igraph.R +++ b/R/fortify-igraph.R @@ -22,35 +22,33 @@ fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), arrow.gap = ifelse(igraph::is.directed(x), 0.025, 0), by = NULL, ...) { - x <- model - # node placement if ( class(layout) == "matrix" && - nrow(layout) == igraph::gorder(x) && + nrow(layout) == igraph::gorder(model) && ncol(layout) == 2 ) { nodes <- layout[, 1:2 ] } else { - nodes <- igraph::layout_(x, layout, ...) + nodes <- igraph::layout_(model, layout, ...) } # store coordinates nodes <- data.frame(nodes) - colnames(nodes) <- c("x", "y") + names(nodes) <- c("x", "y") # rescale coordinates nodes$x <- scale_safely(nodes$x) nodes$y <- scale_safely(nodes$y) # import vertex attributes - if (length(igraph::list.vertex.attributes(x))) { + if (length(igraph::list.vertex.attributes(model))) { nodes <- cbind( nodes, sapply( - igraph::list.vertex.attributes(x), + igraph::list.vertex.attributes(model), FUN = igraph::get.vertex.attribute, - graph = x, + graph = model, USE.NAMES = TRUE ) ) @@ -58,7 +56,7 @@ fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), # edge list - edges <- igraph::as_edgelist(x, names = FALSE) + edges <- igraph::as_edgelist(model, names = FALSE) # edge list (if there are duplicated rows) if (nrow(edges[, 1:2]) > nrow(unique(edges[, 1:2]))) { @@ -73,18 +71,25 @@ fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), x.length <- edges$xend - edges$x y.length <- edges$yend - edges$y arrow.gap <- edges$arrow.gap / sqrt(x.length^2 + y.length^2) - edges$xend <- edges$x + (1 - arrow.gap) * x.length - edges$yend <- edges$y + (1 - arrow.gap) * y.length + # edges$xend <- edges$x + (1 - arrow.gap) * x.length + # edges$yend <- edges$y + (1 - arrow.gap) * y.length + edges <- transform( + edges, + # x = x + arrow.gap * x.length, + # y = y + arrow.gap * y.length, + xend = x + (1 - arrow.gap) * x.length, + yend = y + (1 - arrow.gap) * y.length + ) } # import edge attributes - if (length(igraph::list.edge.attributes(x))) { + if (length(igraph::list.edge.attributes(model))) { edges <- cbind( edges, sapply( - igraph::list.edge.attributes(x), + igraph::list.edge.attributes(model), FUN = igraph::get.edge.attribute, - graph = x, + graph = model, USE.NAMES = TRUE ) ) @@ -104,16 +109,16 @@ fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), # panelize nodes (for temporal networks) if (!is.null(by)) { - nodes <- lapply(sort(unique(edges[, by ])), function(x) { + nodes <- lapply(sort(unique(edges[, by])), function(x) { y <- nodes - y[, by ] <- x + y[, by] <- x y }) nodes <- do.call(rbind, nodes) } - # return a data frame with network.size(x) + network.edgecount(x) rows, - # or length(unique(edges[, by ])) * network.size(x) + network.edgecount(x) + # return a data frame with network.size(model) + network.edgecount(model) rows, + # or length(unique(edges[, by])) * network.size(model) + network.edgecount(model) # rows if the nodes have been panelized - unique(rbind(nodes, edges[ !is.na(edges$xend), ])) + unique(rbind(nodes, edges[!is.na(edges$xend), ])) } diff --git a/R/fortify-network.R b/R/fortify-network.R index af5bdd0..e38da3e 100644 --- a/R/fortify-network.R +++ b/R/fortify-network.R @@ -1,7 +1,3 @@ -if (getRversion() >= "2.15.1") { - utils::globalVariables(c("xend", "yend")) -} - #' Fortify method for networks of class \code{\link[network]{network}} #' #' See the vignette at \url{https://briatte.github.io/ggnetwork/} for a @@ -115,12 +111,10 @@ fortify.network <- function(model, data = NULL, arrow.gap = ifelse(network::is.directed(model), 0.025, 0), by = NULL, ...) { - x <- model - # node placement if ( class(layout) == "matrix" && - nrow(layout) == network::network.size(x) && + nrow(layout) == network::network.size(model) && ncol(layout) == 2 ) { nodes <- layout[, 1:2 ] @@ -130,7 +124,7 @@ fortify.network <- function(model, data = NULL, if (!exists(layout, envir = ns, inherits = FALSE)) { stop("unsupported layout") } - nodes <- do.call(utils::getFromNamespace(layout, ns), list(x, layout.par = list(...))) + nodes <- do.call(utils::getFromNamespace(layout, ns), list(model, layout.par = list(...))) } # store coordinates @@ -142,13 +136,13 @@ fortify.network <- function(model, data = NULL, nodes$y <- scale_safely(nodes$y) # import vertex attributes - for (y in network::list.vertex.attributes(x)) { - nodes <- cbind(nodes, network::get.vertex.attribute(x, y)) + for (y in network::list.vertex.attributes(model)) { + nodes <- cbind(nodes, network::get.vertex.attribute(model, y)) names(nodes)[ncol(nodes)] <- y } # edge list - edges <- network::as.matrix.network.edgelist(x, attrname = weights) + edges <- network::as.matrix.network.edgelist(model, attrname = weights) # edge list (if there are duplicated rows) if (nrow(edges[, 1:2, drop = FALSE]) > nrow(unique(edges[, 1:2, drop = FALSE]))) { @@ -163,14 +157,21 @@ fortify.network <- function(model, data = NULL, x.length <- edges$xend - edges$x y.length <- edges$yend - edges$y arrow.gap <- edges$arrow.gap / sqrt(x.length^2 + y.length^2) - edges$xend <- edges$x + (1 - arrow.gap) * x.length - edges$yend <- edges$y + (1 - arrow.gap) * y.length + # edges$xend <- edges$x + (1 - arrow.gap) * x.length + # edges$yend <- edges$y + (1 - arrow.gap) * y.length + edges <- transform( + edges, + # x = x + arrow.gap * x.length, + # y = y + arrow.gap * y.length, + xend = x + (1 - arrow.gap) * x.length, + yend = y + (1 - arrow.gap) * y.length + ) } # import edge attributes - for (y in network::list.edge.attributes(x)) { - edges <- cbind(edges, network::get.edge.attribute(x, y)) - names(edges)[ncol(edges)] <- y + for (iattribute in network::list.edge.attributes(model)) { + edges <- cbind(edges, network::get.edge.attribute(model, iattribute)) + names(edges)[ncol(edges)] <- iattribute } if (nrow(edges) != 0) { @@ -190,18 +191,18 @@ fortify.network <- function(model, data = NULL, # panelize nodes (for temporal networks) if (!is.null(by)) { - nodes <- lapply(sort(unique(edges[, by ])), function(x) { + nodes <- lapply(sort(unique(edges[, by])), function(x) { y <- nodes - y[, by ] <- x + y[, by] <- x y }) nodes <- do.call(rbind, nodes) } - # return a data frame with network.size(x) + network.edgecount(x) rows, - # or length(unique(edges[, by ])) * network.size(x) + network.edgecount(x) + # return a data frame with network.size(model) + network.edgecount(model) rows, + # or length(unique(edges[, by ])) * network.size(model) + network.edgecount(model) # rows if the nodes have been panelized - return(unique(rbind(nodes, edges[ !is.na(edges$xend), ]))) + return(unique(rbind(nodes, edges[!is.na(edges$xend), ]))) } else { # add missing columns to nodes data nodes$xend <- nodes$x From f54fe00613e41ac13cf6ae31dd2c45ec8808c6ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 17:44:48 +0200 Subject: [PATCH 26/48] remove unnecessary import --- NAMESPACE | 1 - 1 file changed, 1 deletion(-) diff --git a/NAMESPACE b/NAMESPACE index 6411436..6b319d9 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -28,4 +28,3 @@ importFrom(ggplot2,position_nudge) importFrom(ggplot2,unit) importFrom(ggrepel,GeomLabelRepel) importFrom(ggrepel,GeomTextRepel) -importFrom(utils,installed.packages) From b9b0df98781817bcf01354a8c7e7e67ba645312d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 17:45:10 +0200 Subject: [PATCH 27/48] Fix CRAN check for undefined global variable --- R/fortify-igraph.R | 16 ++++------------ R/fortify-network.R | 13 +++---------- man/fortify.igraph.Rd | 3 ++- tests/testthat/test-fortify.R | 20 +++++++++++++++----- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/R/fortify-igraph.R b/R/fortify-igraph.R index cba1203..f6f93d6 100644 --- a/R/fortify-igraph.R +++ b/R/fortify-igraph.R @@ -17,10 +17,9 @@ #' @param ... additional parameters for the \code{\link[igraph]{layout_}} #' function #' @method fortify igraph -#' @importFrom utils installed.packages #' @export fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), - arrow.gap = ifelse(igraph::is.directed(x), 0.025, 0), + arrow.gap = ifelse(igraph::is.directed(model), 0.025, 0), by = NULL, ...) { # node placement if ( @@ -70,16 +69,9 @@ fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), if (arrow.gap > 0) { x.length <- edges$xend - edges$x y.length <- edges$yend - edges$y - arrow.gap <- edges$arrow.gap / sqrt(x.length^2 + y.length^2) - # edges$xend <- edges$x + (1 - arrow.gap) * x.length - # edges$yend <- edges$y + (1 - arrow.gap) * y.length - edges <- transform( - edges, - # x = x + arrow.gap * x.length, - # y = y + arrow.gap * y.length, - xend = x + (1 - arrow.gap) * x.length, - yend = y + (1 - arrow.gap) * y.length - ) + arrow.gap <- arrow.gap / sqrt(x.length^2 + y.length^2) + edges$xend <- edges$x + (1 - arrow.gap) * x.length + edges$yend <- edges$y + (1 - arrow.gap) * y.length } # import edge attributes diff --git a/R/fortify-network.R b/R/fortify-network.R index e38da3e..fa266ac 100644 --- a/R/fortify-network.R +++ b/R/fortify-network.R @@ -156,16 +156,9 @@ fortify.network <- function(model, data = NULL, if (arrow.gap > 0) { x.length <- edges$xend - edges$x y.length <- edges$yend - edges$y - arrow.gap <- edges$arrow.gap / sqrt(x.length^2 + y.length^2) - # edges$xend <- edges$x + (1 - arrow.gap) * x.length - # edges$yend <- edges$y + (1 - arrow.gap) * y.length - edges <- transform( - edges, - # x = x + arrow.gap * x.length, - # y = y + arrow.gap * y.length, - xend = x + (1 - arrow.gap) * x.length, - yend = y + (1 - arrow.gap) * y.length - ) + arrow.gap <- arrow.gap / sqrt(x.length^2 + y.length^2) + edges$xend <- edges$x + (1 - arrow.gap) * x.length + edges$yend <- edges$y + (1 - arrow.gap) * y.length } # import edge attributes diff --git a/man/fortify.igraph.Rd b/man/fortify.igraph.Rd index 1fdac4a..0e2b592 100644 --- a/man/fortify.igraph.Rd +++ b/man/fortify.igraph.Rd @@ -5,7 +5,8 @@ \title{Fortify method for networks of class \code{\link[igraph:igraph-package]{igraph}}} \usage{ \method{fortify}{igraph}(model, data = NULL, layout = igraph::nicely(), - arrow.gap = ifelse(igraph::is.directed(x), 0.025, 0), by = NULL, ...) + arrow.gap = ifelse(igraph::is.directed(model), 0.025, 0), by = NULL, + ...) } \arguments{ \item{model}{an object of class \code{\link[igraph:igraph-package]{igraph}}} diff --git a/tests/testthat/test-fortify.R b/tests/testthat/test-fortify.R index b3cba8f..d6ef0e9 100644 --- a/tests/testthat/test-fortify.R +++ b/tests/testthat/test-fortify.R @@ -2,21 +2,31 @@ context("Test ggnetwork") data(flo, package = "network") -library(network) -library(sna) +# library(network) +# library(sna) test_that("fortify.network works", { - n <- network(flo, directed = FALSE) + n <- network::network(flo, directed = FALSE) expect_is(fortify(n), "data.frame") expect_true(all(c("x", "y", "xend", "yend") %in% names(fortify(n)))) - ggplot(n, aes(x, y, xend = xend, yend = yend)) + + expect_s3_class({ + ggplot(n, aes(x, y, xend = xend, yend = yend)) + geom_nodes() + geom_edges() + geom_nodetext(aes(label = vertex.names)) + geom_edgetext(aes(label = 1)) + theme_blank() + }, class = "ggplot") + + expect_s3_class({ + data(emon, package = "network") + ggplot(emon[[1]], aes(x = x, y = y, xend = xend, yend = yend)) + + geom_edges() + + geom_nodes(color = "tomato", size = 4) + + theme_blank() + }, class = "ggplot") }) test_that("fortify.igraph works", { @@ -28,7 +38,7 @@ test_that("fortify.igraph works", { ggplot(n, aes(x, y, xend = xend, yend = yend)) + geom_edges() + geom_nodes() + - geom_nodetext(aes(label = vertex.names)) + + geom_nodetext(aes(label = name)) + geom_edgetext(aes(label = 1)) + theme_blank() }) From 2fb25d7d20c154cc5f8ee54a7b78399ff5604981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 18:26:25 +0200 Subject: [PATCH 28/48] restyle roxygen --- R/fortify-igraph.R | 34 ++++++++++++++----------- R/fortify-network.R | 62 +++++++++++++++++++++++++-------------------- 2 files changed, 53 insertions(+), 43 deletions(-) diff --git a/R/fortify-igraph.R b/R/fortify-igraph.R index f6f93d6..5ded135 100644 --- a/R/fortify-igraph.R +++ b/R/fortify-igraph.R @@ -3,24 +3,28 @@ #' @param model an object of class \code{\link[igraph:igraph-package]{igraph}} #' @param data not used by this method. #' @param layout a function call to an -#' \code{\link[igraph:igraph-package]{igraph}} layout function, such as -#' \code{\link[igraph]{layout_nicely}} (the default), or a 2 column matrix -#' giving the x and y coordinates for the vertices. -#' See \code{\link[igraph]{layout_}} for details. +#' \code{\link[igraph:igraph-package]{igraph}} layout function, such as +#' \code{\link[igraph]{layout_nicely}} (the default), or a 2 column matrix +#' giving the x and y coordinates for the vertices. +#' See \code{\link[igraph]{layout_}} for details. #' @param arrow.gap a parameter that will shorten the network edges in order to -#' avoid overplotting edge arrows and nodes; defaults to \code{0} when the -#' network is undirected (no edge shortening), or to \code{0.025} when the -#' network is directed. Small values near \code{0.025} will generally achieve -#' good results when the size of the nodes is reasonably small. +#' avoid overplotting edge arrows and nodes; defaults to \code{0} when the +#' network is undirected (no edge shortening), or to \code{0.025} when the +#' network is directed. Small values near \code{0.025} will generally achieve +#' good results when the size of the nodes is reasonably small. #' @param by a character vector that matches an edge attribute, which will be -#' used to generate a data frame that can be plotted with -#' @param ... additional parameters for the \code{\link[igraph]{layout_}} -#' function -#' @method fortify igraph +#' used to generate a data frame that can be plotted with +#' @param ... additional parameters for the \code{\link[igraph]{layout_}} function +#' #' @export -fortify.igraph <- function(model, data = NULL, layout = igraph::nicely(), - arrow.gap = ifelse(igraph::is.directed(model), 0.025, 0), - by = NULL, ...) { +fortify.igraph <- function( + model, + data = NULL, + layout = igraph::nicely(), + arrow.gap = ifelse(igraph::is.directed(model), 0.025, 0), + by = NULL, + ... +) { # node placement if ( class(layout) == "matrix" && diff --git a/R/fortify-network.R b/R/fortify-network.R index fa266ac..f6b35d9 100644 --- a/R/fortify-network.R +++ b/R/fortify-network.R @@ -3,37 +3,38 @@ #' See the vignette at \url{https://briatte.github.io/ggnetwork/} for a #' description of both this function and the rest of the \code{ggnetwork} #' package. +#' #' @param model an object of class \code{\link[network]{network}}. #' @param data not used by this method. #' @param layout a network layout supplied by \code{\link[sna]{gplot.layout}}, -#' such as \code{"fruchtermanreingold"} (the default), or a two-column matrix -#' with as many rows as there are nodes in the network, in which case the -#' matrix is used as nodes coordinates. +#' such as \code{"fruchtermanreingold"} (the default), or a two-column matrix +#' with as many rows as there are nodes in the network, in which case the +#' matrix is used as nodes coordinates. #' @param weights the name of an edge attribute to use as edge weights when -#' computing the network layout, if the layout supports such weights (see -#' 'Details'). -#' Defaults to \code{NULL} (no edge weights). +#' computing the network layout, if the layout supports such weights (see +#' 'Details'). +#' Defaults to \code{NULL} (no edge weights). #' @param arrow.gap a parameter that will shorten the network edges in order to -#' avoid overplotting edge arrows and nodes; defaults to \code{0} when the -#' network is undirected (no edge shortening), or to \code{0.025} when the -#' network is directed. Small values near \code{0.025} will generally achieve -#' good results when the size of the nodes is reasonably small. +#' avoid overplotting edge arrows and nodes; defaults to \code{0} when the +#' network is undirected (no edge shortening), or to \code{0.025} when the +#' network is directed. Small values near \code{0.025} will generally achieve +#' good results when the size of the nodes is reasonably small. #' @param by a character vector that matches an edge attribute, which will be -#' used to generate a data frame that can be plotted with -#' \code{\link[ggplot2]{facet_wrap}} or \code{\link[ggplot2]{facet_grid}}. The -#' nodes of the network will appear in all facets, at the same coordinates. -#' Defaults to \code{NULL} (no faceting). -#' @return a data.frame object. +#' used to generate a data frame that can be plotted with +#' \code{\link[ggplot2]{facet_wrap}} or \code{\link[ggplot2]{facet_grid}}. The +#' nodes of the network will appear in all facets, at the same coordinates. +#' Defaults to \code{NULL} (no faceting). #' @param ... additional parameters for the \code{layout} argument; see -#' \code{\link[sna]{gplot.layout}} for available options. +#' \code{\link[sna]{gplot.layout}} for available options. +#' #' @details \code{fortify.network} will return a warning if it finds duplicated -#' edges after converting the network to an edge list. Duplicated edges should -#' be eliminated in favour of single weighted edges before using a network -#' layout that supports edge weights, such as the Kamada-Kawai force-directed -#' placement algorithm. -#' @import sna -#' @importFrom ggplot2 fortify -#' @method fortify network +#' edges after converting the network to an edge list. Duplicated edges should +#' be eliminated in favour of single weighted edges before using a network +#' layout that supports edge weights, such as the Kamada-Kawai force-directed +#' placement algorithm. +#' +#' @return a data.frame object. +#' #' @examples #' if (require(ggplot2) && require(network)) { #' @@ -105,12 +106,17 @@ #' geom_nodes() + #' theme_blank() #' } +#' #' @export -fortify.network <- function(model, data = NULL, - layout = "fruchtermanreingold", weights = NULL, - arrow.gap = ifelse(network::is.directed(model), 0.025, 0), - by = NULL, - ...) { +fortify.network <- function( + model, + data = NULL, + layout = "fruchtermanreingold", + weights = NULL, + arrow.gap = ifelse(network::is.directed(model), 0.025, 0), + by = NULL, + ... +) { # node placement if ( class(layout) == "matrix" && From fdd9e5a170560fc5272b9064020e646f98a26dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 18:26:39 +0200 Subject: [PATCH 29/48] remove unnecessary "@importFom". add missing function packages prefix. --- R/geom-edges.R | 128 +++++++++++++++++++--------------- R/geom-nodes.R | 185 +++++++++++++++++++++++++++---------------------- 2 files changed, 173 insertions(+), 140 deletions(-) diff --git a/R/geom-edges.R b/R/geom-edges.R index 71ed1e3..41668b5 100644 --- a/R/geom-edges.R +++ b/R/geom-edges.R @@ -7,9 +7,10 @@ #' \code{ncp} arguments of \code{\link[ggplot2]{geom_curve}} are also available: #' if \code{curvature} is set to any value above \code{0} (the default), the #' edges produced by \code{geom_edges} will be curved. +#' #' @inheritParams ggplot2::geom_segment #' @inheritParams ggplot2::geom_curve -#' @importFrom ggplot2 GeomSegment GeomCurve layer +#' #' @examples #' if (require(network) && require(sna)) { #' @@ -78,19 +79,24 @@ #' scale_colour_gradient(low = "gold", high = "tomato") + #' theme_blank() #' } +#' #' @export -geom_edges <- function(mapping = NULL, data = NULL, - position = "identity", arrow = NULL, - curvature = 0, angle = 90, ncp = 5, - na.rm = FALSE, show.legend = NA, inherit.aes = TRUE, - ...) { +geom_edges <- function( + mapping = NULL, + data = NULL, + position = "identity", + arrow = NULL, + curvature = 0, + angle = 90, + ncp = 5, + na.rm = FALSE, + show.legend = NA, + inherit.aes = TRUE, + ... +) { if (!curvature) { geom <- ggplot2::GeomSegment - params <- list( - arrow = arrow, - na.rm = na.rm, - ... - ) + params <- list(arrow = arrow, na.rm = na.rm, ...) } else { geom <- ggplot2::GeomCurve params <- list( @@ -127,10 +133,11 @@ geom_edges <- function(mapping = NULL, data = NULL, #' border around the edge labels. The labels will be drawn at mid-edges. #' \code{\link{geom_text}} and \code{\link{geom_label}} produce strictly #' identical results. +#' #' @inheritParams ggplot2::geom_label #' @param nudge_x,nudge_y Horizontal and vertical adjustment to nudge labels by. #' Useful for offsetting text from points, particularly on discrete scales. -#' @importFrom ggplot2 unit position_nudge layer GeomLabel +#' #' @examples #' if (require(network) && require(sna)) { #' data(flo, package = "network") @@ -157,14 +164,23 @@ geom_edges <- function(mapping = NULL, data = NULL, #' geom_nodes(size = 4, colour = "grey50") + #' theme_blank() #' } +#' #' @export -geom_edgetext <- function(mapping = NULL, data = NULL, - position = "identity", parse = FALSE, ..., - nudge_x = 0, nudge_y = 0, - label.padding = unit(0.25, "lines"), - label.r = ggplot2::unit(0.15, "lines"), - label.size = 0, - na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) { +geom_edgetext <- function( + mapping = NULL, + data = NULL, + position = "identity", + parse = FALSE, + ..., + nudge_x = 0, + nudge_y = 0, + label.padding = unit(0.25, "lines"), + label.r = unit(0.15, "lines"), + label.size = 0, + na.rm = FALSE, + show.legend = NA, + inherit.aes = TRUE +) { if (!missing(nudge_x) || !missing(nudge_y)) { if (!missing(position)) { stop("Specify either `position` or `nudge_x`/`nudge_y`", call. = FALSE) @@ -201,11 +217,11 @@ geom_edgetext <- function(mapping = NULL, data = NULL, #' \code{\link{geom_edgelabel_repel}} are identical to those of #' \code{\link[ggrepel]{geom_label_repel}}. \code{\link{geom_text_repel}} and #' \code{\link{geom_label_repel}} produce strictly identical results. +#' #' @inheritParams ggrepel::geom_label_repel #' @param nudge_x,nudge_y Horizontal and vertical adjustments to nudge the #' starting position of each text label. -#' @importFrom ggplot2 layer -#' @importFrom ggrepel GeomLabelRepel +#' #' @examples #' if (require(network) && require(sna)) { #' data(flo, package = "network") @@ -239,27 +255,29 @@ geom_edgetext <- function(mapping = NULL, data = NULL, #' ) + #' theme_blank() #' } +#' #' @export geom_edgetext_repel <- function( - mapping = NULL, data = NULL, - parse = FALSE, - ..., - box.padding = unit(0.25, "lines"), - label.padding = unit(0.25, "lines"), - point.padding = unit(1e-6, "lines"), - label.r = unit(0.15, "lines"), - label.size = 0.25, - segment.colour = "#666666", - segment.size = 0.5, - arrow = NULL, - force = 1, - max.iter = 2000, - nudge_x = 0, - nudge_y = 0, - na.rm = FALSE, - show.legend = NA, - inherit.aes = TRUE) { - layer( + mapping = NULL, data = NULL, + parse = FALSE, + ..., + box.padding = unit(0.25, "lines"), + label.padding = unit(0.25, "lines"), + point.padding = unit(1e-6, "lines"), + label.r = unit(0.15, "lines"), + label.size = 0.25, + segment.colour = "#666666", + segment.size = 0.5, + arrow = NULL, + force = 1, + max.iter = 2000, + nudge_x = 0, + nudge_y = 0, + na.rm = FALSE, + show.legend = NA, + inherit.aes = TRUE +) { + ggplot2::layer( data = data, mapping = mapping, stat = StatMidEdges, @@ -295,23 +313,19 @@ geom_edgelabel <- geom_edgetext #' @export geom_edgelabel_repel <- geom_edgetext_repel -#' @importFrom ggplot2 ggproto #' @keywords internal -StatEdges <- - ggplot2::ggproto("StatEdges", ggplot2::Stat, - compute_layer = function(data, scales, params) { - unique(subset(data, !(x == xend & y == yend))) - } - ) +StatEdges <- ggplot2::ggproto("StatEdges", ggplot2::Stat, + compute_layer = function(data, scales, params) { + unique(subset(data, !(x == xend & y == yend))) + } +) -#' @importFrom ggplot2 ggproto #' @keywords internal -StatMidEdges <- - ggplot2::ggproto("StatMidEdges", ggplot2::Stat, - compute_layer = function(data, scales, params) { - data <- subset(data, !(x == xend & y == yend)) - data$x <- (data$x + data$xend) / 2 - data$y <- (data$y + data$yend) / 2 - unique(subset(data, select = c(-xend, -yend))) - } - ) +StatMidEdges <- ggplot2::ggproto("StatMidEdges", ggplot2::Stat, + compute_layer = function(data, scales, params) { + data <- subset(data, !(x == xend & y == yend)) + data$x <- (data$x + data$xend) / 2 + data$y <- (data$y + data$yend) / 2 + unique(subset(data, select = c(-xend, -yend))) + } +) diff --git a/R/geom-nodes.R b/R/geom-nodes.R index b93bad1..6b0c41b 100644 --- a/R/geom-nodes.R +++ b/R/geom-nodes.R @@ -2,8 +2,9 @@ #' #' All arguments to this geom are identical to those of #' \code{\link[ggplot2]{geom_point}}. +#' #' @inheritParams ggplot2::geom_point -#' @importFrom ggplot2 layer GeomPoint +#' #' @examples #' if (require(network) && require(sna)) { #' data(flo, package = "network") @@ -36,10 +37,17 @@ #' theme_blank() + #' theme(legend.position = "bottom") #' } +#' #' @export -geom_nodes <- function(mapping = NULL, data = NULL, - position = "identity", na.rm = FALSE, - show.legend = NA, inherit.aes = TRUE, ...) { +geom_nodes <- function( + mapping = NULL, + data = NULL, + position = "identity", + na.rm = FALSE, + show.legend = NA, + inherit.aes = TRUE, + ... +) { ggplot2::layer( data = data, mapping = mapping, @@ -62,11 +70,11 @@ geom_nodes <- function(mapping = NULL, data = NULL, #' #' All arguments to these geoms are identical to those of #' \code{\link[ggplot2]{geom_text}} and \code{\link[ggplot2]{geom_label}}. +#' #' @inheritParams ggplot2::geom_text #' @param nudge_x,nudge_y Horizontal and vertical adjustment to nudge labels by. #' Useful for offsetting text from points, particularly on discrete scales. -#' @importFrom ggplot2 position_nudge layer GeomText -#' @export +#' #' @examples #' ## geom_nodetext examples #' @@ -91,22 +99,25 @@ geom_nodes <- function(mapping = NULL, data = NULL, #' geom_nodetext(aes(label = vertex.names)) + #' theme_blank() #' } -geom_nodetext <- function(mapping = NULL, - data = NULL, - position = "identity", - ..., - parse = FALSE, - nudge_x = 0, - nudge_y = 0, - check_overlap = FALSE, - na.rm = FALSE, - show.legend = NA, - inherit.aes = TRUE) { +#' +#' @export +geom_nodetext <- function( + mapping = NULL, + data = NULL, + position = "identity", + ..., + parse = FALSE, + nudge_x = 0, + nudge_y = 0, + check_overlap = FALSE, + na.rm = FALSE, + show.legend = NA, + inherit.aes = TRUE +) { if (!missing(nudge_x) || !missing(nudge_y)) { if (!missing(position)) { stop("Specify either `position` or `nudge_x`/`nudge_y`", call. = FALSE) } - position <- ggplot2::position_nudge(nudge_x, nudge_y) } @@ -135,11 +146,11 @@ geom_nodetext <- function(mapping = NULL, #' All arguments to these geoms are identical to those of #' \code{\link[ggrepel]{geom_text_repel}} and #' \code{\link[ggrepel]{geom_label_repel}}. +#' #' @inheritParams ggrepel::geom_text_repel #' @param nudge_x,nudge_y Horizontal and vertical adjustments to nudge the #' starting position of each text label. -#' @importFrom ggplot2 layer -#' @importFrom ggrepel GeomTextRepel +#' #' @examples #' ## geom_nodetext_repel example #' @@ -153,24 +164,27 @@ geom_nodetext <- function(mapping = NULL, #' geom_nodes(colour = "steelblue", size = 3) + #' theme_blank() #' } +#' #' @export -geom_nodetext_repel <- function(mapping = NULL, - data = NULL, - # stat = "identity", - parse = FALSE, - ..., - box.padding = unit(0.25, "lines"), - point.padding = unit(1e-06, "lines"), - segment.colour = "#666666", - segment.size = 0.5, - arrow = NULL, - force = 1, - max.iter = 2000, - nudge_x = 0, - nudge_y = 0, - na.rm = FALSE, - show.legend = NA, - inherit.aes = TRUE) { +geom_nodetext_repel <- function( + mapping = NULL, + data = NULL, + # stat = "identity", + parse = FALSE, + ..., + box.padding = unit(0.25, "lines"), + point.padding = unit(1e-06, "lines"), + segment.colour = "#666666", + segment.size = 0.5, + arrow = NULL, + force = 1, + max.iter = 2000, + nudge_x = 0, + nudge_y = 0, + na.rm = FALSE, + show.legend = NA, + inherit.aes = TRUE +) { ggplot2::layer( data = data, mapping = mapping, @@ -197,8 +211,9 @@ geom_nodetext_repel <- function(mapping = NULL, } #' @rdname geom_nodetext +#' #' @inheritParams ggplot2::geom_label -#' @importFrom ggplot2 position_nudge layer GeomLabel +#' #' @examples #' #' ## geom_nodelabel examples @@ -234,28 +249,31 @@ geom_nodetext_repel <- function(mapping = NULL, #' ) + #' theme_blank() #' } +#' #' @export -geom_nodelabel <- function(mapping = NULL, data = NULL, - position = "identity", - ..., - parse = FALSE, - nudge_x = 0, - nudge_y = 0, - label.padding = unit(0.25, "lines"), - label.r = unit(0.15, "lines"), - label.size = 0.25, - na.rm = FALSE, - show.legend = NA, - inherit.aes = TRUE) { +geom_nodelabel <- function( + mapping = NULL, + data = NULL, + position = "identity", + ..., + parse = FALSE, + nudge_x = 0, + nudge_y = 0, + label.padding = unit(0.25, "lines"), + label.r = unit(0.15, "lines"), + label.size = 0.25, + na.rm = FALSE, + show.legend = NA, + inherit.aes = TRUE +) { if (!missing(nudge_x) || !missing(nudge_y)) { if (!missing(position)) { stop("Specify either `position` or `nudge_x`/`nudge_y`", call. = FALSE) } - position <- ggplot2::position_nudge(nudge_x, nudge_y) } - layer( + ggplot2::layer( data = data, mapping = mapping, stat = StatNodes, @@ -275,9 +293,9 @@ geom_nodelabel <- function(mapping = NULL, data = NULL, } #' @rdname geom_nodetext_repel +#' #' @inheritParams ggrepel::geom_label_repel -#' @importFrom ggplot2 layer -#' @importFrom ggrepel GeomLabelRepel +#' #' @examples #' ## geom_nodelabel_repel examples #' @@ -309,27 +327,30 @@ geom_nodelabel <- function(mapping = NULL, data = NULL, #' geom_nodes(aes(size = degree), colour = "steelblue") + #' theme_blank() #' } +#' #' @export geom_nodelabel_repel <- function( - mapping = NULL, data = NULL, - parse = FALSE, - ..., - box.padding = unit(0.25, "lines"), - label.padding = unit(0.25, "lines"), - point.padding = unit(1e-6, "lines"), - label.r = unit(0.15, "lines"), - label.size = 0.25, - segment.colour = "#666666", - segment.size = 0.5, - arrow = NULL, - force = 1, - max.iter = 2000, - nudge_x = 0, - nudge_y = 0, - na.rm = FALSE, - show.legend = NA, - inherit.aes = TRUE) { - layer( + mapping = NULL, + data = NULL, + parse = FALSE, + ..., + box.padding = unit(0.25, "lines"), + label.padding = unit(0.25, "lines"), + point.padding = unit(1e-6, "lines"), + label.r = unit(0.15, "lines"), + label.size = 0.25, + segment.colour = "#666666", + segment.size = 0.5, + arrow = NULL, + force = 1, + max.iter = 2000, + nudge_x = 0, + nudge_y = 0, + na.rm = FALSE, + show.legend = NA, + inherit.aes = TRUE +) { + ggplot2::layer( data = data, mapping = mapping, stat = StatNodes, @@ -357,15 +378,13 @@ geom_nodelabel_repel <- function( ) } -#' @importFrom ggplot2 ggproto #' @keywords internal -StatNodes <- - ggplot2::ggproto("StatNodes", ggplot2::Stat, - compute_layer = function(data, scales, params) { - if (all(c("xend", "yend") %in% names(data))) { - unique(subset(data, select = c(-xend, -yend))) - } else { - unique(data) - } +StatNodes <- ggplot2::ggproto("StatNodes", ggplot2::Stat, + compute_layer = function(data, scales, params) { + if (all(c("xend", "yend") %in% names(data))) { + unique(subset(data, select = c(-xend, -yend))) + } else { + unique(data) } - ) + } +) From 57eb49ce4872e0bf16d37b5862497d3844548678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 18:26:52 +0200 Subject: [PATCH 30/48] reexport `fortify` and `unit` from `ggplot2`. --- R/utilities.R | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/R/utilities.R b/R/utilities.R index f36c4fe..9410b38 100644 --- a/R/utilities.R +++ b/R/utilities.R @@ -2,9 +2,11 @@ #' #' A \code{ggplot2} theme without lines, borders, axis text or titles, suited #' for plotting networks. +#' #' @param base_size base font size #' @param base_family base font family #' @param ... other \code{\link{theme}} arguments +#' #' @export theme_blank <- function(base_size = 12, base_family = "", ...) { ggplot2::theme_bw(base_size = base_size, base_family = base_family) + @@ -24,9 +26,11 @@ theme_blank <- function(base_size = 12, base_family = "", ...) { #' #' A variation of \code{\link{theme_blank}} that adds a panel border to the #' plot, which is often suitable for plotting faceted networks. +#' #' @param base_size base font size #' @param base_family base font family #' @param ... other \code{\link{theme}} arguments +#' #' @export theme_facet <- function(base_size = 12, base_family = "", ...) { theme_blank(base_size = base_size, base_family = base_family) + @@ -41,14 +45,40 @@ theme_facet <- function(base_size = 12, base_family = "", ...) { #' Discussed in PR #32: https://github.com/briatte/ggnetwork/pull/32 #' @param x a vector to rescale #' @param scale the scale on which to rescale the vector +#' #' @return The rescaled vector, coerced to a vector if necessary. -#' If the original vector was constant, all of its values are replaced by 0.5. +#' If the original vector was constant, all of its values are replaced by 0.5. +#' #' @author Kipp Johnson scale_safely <- function(x, scale = diff(range(x))) { if (!scale) { x <- rep(0.5, length.out = length(x)) } else { - x <- base::scale(x, center = min(x), scale = scale) + x <- scale(x, center = min(x), scale = scale) } as.vector(x) } + +#' fortify generic +#' +#' See \code{ggplot2::\link[ggplot2]{fortify}} for details. +#' +#' @name fortify +#' @rdname fortify +#' @keywords internal +#' @export +#' @importFrom ggplot2 fortify +NULL + + + +#' unit +#' +#' See \code{ggplot2::\link[ggplot2]{unit}} for details. +#' +#' @name unit +#' @rdname unit +#' @keywords internal +#' @export +#' @importFrom ggplot2 unit +NULL From d703f871b8c7c140fad586ad96afecb2490b76bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 18:27:03 +0200 Subject: [PATCH 31/48] update doc --- man/fortify.Rd | 9 +++++++++ man/fortify.igraph.Rd | 3 +-- man/fortify.network.Rd | 1 + man/geom_edges.Rd | 1 + man/geom_edgetext.Rd | 9 +++++---- man/geom_edgetext_repel.Rd | 1 + man/geom_nodes.Rd | 1 + man/geom_nodetext.Rd | 2 ++ man/geom_nodetext_repel.Rd | 2 ++ man/unit.Rd | 9 +++++++++ 10 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 man/fortify.Rd create mode 100644 man/unit.Rd diff --git a/man/fortify.Rd b/man/fortify.Rd new file mode 100644 index 0000000..e07fce8 --- /dev/null +++ b/man/fortify.Rd @@ -0,0 +1,9 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utilities.R +\name{fortify} +\alias{fortify} +\title{fortify generic} +\description{ +See \code{ggplot2::\link[ggplot2]{fortify}} for details. +} +\keyword{internal} diff --git a/man/fortify.igraph.Rd b/man/fortify.igraph.Rd index 0e2b592..07d0768 100644 --- a/man/fortify.igraph.Rd +++ b/man/fortify.igraph.Rd @@ -28,8 +28,7 @@ good results when the size of the nodes is reasonably small.} \item{by}{a character vector that matches an edge attribute, which will be used to generate a data frame that can be plotted with} -\item{...}{additional parameters for the \code{\link[igraph]{layout_}} -function} +\item{...}{additional parameters for the \code{\link[igraph]{layout_}} function} } \description{ Fortify method for networks of class \code{\link[igraph:igraph-package]{igraph}} diff --git a/man/fortify.network.Rd b/man/fortify.network.Rd index ebf21d9..2355aa4 100644 --- a/man/fortify.network.Rd +++ b/man/fortify.network.Rd @@ -125,4 +125,5 @@ if (require(ggplot2) && require(network)) { geom_nodes() + theme_blank() } + } diff --git a/man/geom_edges.Rd b/man/geom_edges.Rd index 9d28ad4..6003956 100644 --- a/man/geom_edges.Rd +++ b/man/geom_edges.Rd @@ -143,4 +143,5 @@ if (require(network) && require(sna)) { scale_colour_gradient(low = "gold", high = "tomato") + theme_blank() } + } diff --git a/man/geom_edgetext.Rd b/man/geom_edgetext.Rd index f07782b..ad54032 100644 --- a/man/geom_edgetext.Rd +++ b/man/geom_edgetext.Rd @@ -7,14 +7,14 @@ \usage{ geom_edgetext(mapping = NULL, data = NULL, position = "identity", parse = FALSE, ..., nudge_x = 0, nudge_y = 0, - label.padding = unit(0.25, "lines"), label.r = ggplot2::unit(0.15, - "lines"), label.size = 0, na.rm = FALSE, show.legend = NA, + label.padding = unit(0.25, "lines"), label.r = unit(0.15, "lines"), + label.size = 0, na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) geom_edgelabel(mapping = NULL, data = NULL, position = "identity", parse = FALSE, ..., nudge_x = 0, nudge_y = 0, - label.padding = unit(0.25, "lines"), label.r = ggplot2::unit(0.15, - "lines"), label.size = 0, na.rm = FALSE, show.legend = NA, + label.padding = unit(0.25, "lines"), label.r = unit(0.15, "lines"), + label.size = 0, na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) } \arguments{ @@ -107,4 +107,5 @@ if (require(network) && require(sna)) { geom_nodes(size = 4, colour = "grey50") + theme_blank() } + } diff --git a/man/geom_edgetext_repel.Rd b/man/geom_edgetext_repel.Rd index 0843f0e..051539f 100644 --- a/man/geom_edgetext_repel.Rd +++ b/man/geom_edgetext_repel.Rd @@ -132,4 +132,5 @@ if (require(network) && require(sna)) { ) + theme_blank() } + } diff --git a/man/geom_nodes.Rd b/man/geom_nodes.Rd index 28e3c5b..5c3dff9 100644 --- a/man/geom_nodes.Rd +++ b/man/geom_nodes.Rd @@ -86,4 +86,5 @@ if (require(network) && require(sna)) { theme_blank() + theme(legend.position = "bottom") } + } diff --git a/man/geom_nodetext.Rd b/man/geom_nodetext.Rd index f690b7b..b5fa7b2 100644 --- a/man/geom_nodetext.Rd +++ b/man/geom_nodetext.Rd @@ -103,6 +103,7 @@ if (require(network) && require(sna)) { theme_blank() } + ## geom_nodelabel examples if (require(network) && require(sna)) { @@ -136,4 +137,5 @@ if (require(network) && require(sna)) { ) + theme_blank() } + } diff --git a/man/geom_nodetext_repel.Rd b/man/geom_nodetext_repel.Rd index 319674a..a7cd8eb 100644 --- a/man/geom_nodetext_repel.Rd +++ b/man/geom_nodetext_repel.Rd @@ -109,6 +109,7 @@ if (require(network) && require(sna)) { geom_nodes(colour = "steelblue", size = 3) + theme_blank() } + ## geom_nodelabel_repel examples if (require(network) && require(sna)) { @@ -139,4 +140,5 @@ if (require(network) && require(sna)) { geom_nodes(aes(size = degree), colour = "steelblue") + theme_blank() } + } diff --git a/man/unit.Rd b/man/unit.Rd new file mode 100644 index 0000000..5f07b6e --- /dev/null +++ b/man/unit.Rd @@ -0,0 +1,9 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utilities.R +\name{unit} +\alias{unit} +\title{unit} +\description{ +See \code{ggplot2::\link[ggplot2]{unit}} for details. +} +\keyword{internal} From 1d5d6f9a9448c0cab4f4a3b44a2e97eb0090acf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 18:27:22 +0200 Subject: [PATCH 32/48] update namespace --- NAMESPACE | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 6b319d9..b538ae1 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,6 +2,7 @@ S3method(fortify,igraph) S3method(fortify,network) +export(fortify) export(geom_edgelabel) export(geom_edgelabel_repel) export(geom_edges) @@ -15,16 +16,6 @@ export(geom_nodetext_repel) export(ggnetwork) export(theme_blank) export(theme_facet) -import(sna) -importFrom(ggplot2,GeomCurve) -importFrom(ggplot2,GeomLabel) -importFrom(ggplot2,GeomPoint) -importFrom(ggplot2,GeomSegment) -importFrom(ggplot2,GeomText) +export(unit) importFrom(ggplot2,fortify) -importFrom(ggplot2,ggproto) -importFrom(ggplot2,layer) -importFrom(ggplot2,position_nudge) importFrom(ggplot2,unit) -importFrom(ggrepel,GeomLabelRepel) -importFrom(ggrepel,GeomTextRepel) From 04dc597cbf975ce98d249e3733019fa93cb15efa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 18:27:36 +0200 Subject: [PATCH 33/48] add `Collate` field to load sequentially the functions. --- DESCRIPTION | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 18f2c74..f4ebd60 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -14,13 +14,8 @@ Authors@R: c( ) Description: Geometries to plot network objects with 'ggplot2'. License: GPL-3 -Encoding: UTF-8 URL: https://github.com/briatte/ggnetwork BugReports: https://github.com/briatte/ggnetwork/issues -LazyData: true -NeedsCompilation: no -RoxygenNote: 6.1.1 -VignetteBuilder: knitr Depends: ggplot2 (>= 2.0.0), R (>= 3.1), @@ -33,3 +28,16 @@ Suggests: igraph, knitr, testthat +Collate: + 'utilities.R' + 'fortify-igraph.R' + 'fortify-network.R' + 'geom-nodes.R' + 'geom-edges.R' + 'ggnetwork.R' +VignetteBuilder: knitr +RoxygenNote: 6.1.1 +Roxygen: list(markdown = TRUE) +Encoding: UTF-8 +LazyData: true +NeedsCompilation: no From c654d5e70a10ceb30a530ca28921e8e081cf9a6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 18:27:44 +0200 Subject: [PATCH 34/48] update changelog --- NEWS.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NEWS.md b/NEWS.md index 433eef4..ed99721 100644 --- a/NEWS.md +++ b/NEWS.md @@ -29,6 +29,12 @@ ggnetwork 0.5.6 * In `R/fortify-igraph.R` and `R/fortify-network.R`, + use subsetting functions instead of `with` and `transform` (*i.e.*, intended to be use interactively). + fix issue from CRAN check with undefined global variables. + +* In `R/geom-nodes.R` and `R/geom-edges.R`, + + remove unnecessary "@importFom". + + add missing function packages prefix. + +* In `R/utilities.R`, reexport `fortify` and `unit` from `ggplot2`. From 6280cfa1675991749d696b2df516741a9ae799c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 18:28:27 +0200 Subject: [PATCH 35/48] update changelog --- NEWS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index ed99721..77faef4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -20,7 +20,8 @@ ggnetwork 0.5.6 * In `DESCRIPTION`, + update RoxygenNote version. - + Remove `ggplot2` from `Enhances` field. + + remove `ggplot2` from `Enhances` field. + + add `Collate` field to load sequentially the functions. * Remove `inst/doc/` directory, *i.e.*, the vignette is part of the `pkgdown` website. From 9ddebec294149ccdf5f794838f85459f74247d4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 19:07:35 +0200 Subject: [PATCH 36/48] remove namespace loading (sna) --- R/fortify-network.R | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/R/fortify-network.R b/R/fortify-network.R index f6b35d9..29f01d9 100644 --- a/R/fortify-network.R +++ b/R/fortify-network.R @@ -125,12 +125,8 @@ fortify.network <- function( ) { nodes <- layout[, 1:2 ] } else { - layout <- paste0("gplot.layout.", layout) - ns <- loadNamespace("sna") - if (!exists(layout, envir = ns, inherits = FALSE)) { - stop("unsupported layout") - } - nodes <- do.call(utils::getFromNamespace(layout, ns), list(model, layout.par = list(...))) + layout <- eval(parse(text = paste0("sna::gplot.layout.", layout))) + nodes <- do.call(layout, list(model, layout.par = list(...))) } # store coordinates From 7e5cc5188d826cc6b781a92f28e0a2f8ec46ddfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 19:08:47 +0200 Subject: [PATCH 37/48] remove blank lines --- R/utilities.R | 2 -- 1 file changed, 2 deletions(-) diff --git a/R/utilities.R b/R/utilities.R index 9410b38..a5d0e57 100644 --- a/R/utilities.R +++ b/R/utilities.R @@ -70,8 +70,6 @@ scale_safely <- function(x, scale = diff(range(x))) { #' @importFrom ggplot2 fortify NULL - - #' unit #' #' See \code{ggplot2::\link[ggplot2]{unit}} for details. From f6797f79de3abffcb62ff164922531bd62a59210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 19:09:16 +0200 Subject: [PATCH 38/48] add blank lines --- R/ggnetwork.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/ggnetwork.R b/R/ggnetwork.R index 6a2b9ca..b489a6e 100644 --- a/R/ggnetwork.R +++ b/R/ggnetwork.R @@ -11,7 +11,9 @@ #' \code{\link[intergraph:intergraph-package]{intergraph}} package is installed, #' it will be used to convert the object: see #' \code{\link{fortify.igraph}} for details. +#' #' @param ... arguments passed to the \code{\link{fortify.network}} function. +#' #' @export ggnetwork <- function(x, ...) { if (class(x) == "igraph") { From bf60db9a5ab15274d169a0d65d8407fe526b20bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 19:09:37 +0200 Subject: [PATCH 39/48] move igraph to Imports --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index f4ebd60..bc31f6d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -22,10 +22,10 @@ Depends: Imports: ggrepel (>= 0.5), network, + igraph, sna, utils Suggests: - igraph, knitr, testthat Collate: From d809847f368d221444df6ca3061037c99e0e14a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 19:10:19 +0200 Subject: [PATCH 40/48] Improve unit testing --- tests/testthat/test-fortify.R | 16 ++---- tests/testthat/test-geoms.R | 90 ++++++++++++++++++++++----------- tests/testthat/test-ggnetwork.R | 17 ++++--- tests/testthat/test-utilities.R | 22 ++++---- 4 files changed, 87 insertions(+), 58 deletions(-) diff --git a/tests/testthat/test-fortify.R b/tests/testthat/test-fortify.R index d6ef0e9..d03ad12 100644 --- a/tests/testthat/test-fortify.R +++ b/tests/testthat/test-fortify.R @@ -1,14 +1,8 @@ -context("Test ggnetwork") - -data(flo, package = "network") - -# library(network) -# library(sna) - -test_that("fortify.network works", { +test_that("fortify.network", { + data(flo, package = "network") n <- network::network(flo, directed = FALSE) - expect_is(fortify(n), "data.frame") + expect_s3_class(fortify(n), "data.frame") expect_true(all(c("x", "y", "xend", "yend") %in% names(fortify(n)))) expect_s3_class({ @@ -29,10 +23,10 @@ test_that("fortify.network works", { }, class = "ggplot") }) -test_that("fortify.igraph works", { +test_that("fortify.igraph", { n <- igraph::graph_from_adjacency_matrix(flo, mode = "undirected") - expect_is(fortify(n), "data.frame") + expect_s3_class(fortify(n), "data.frame") expect_true(all(c("x", "y", "xend", "yend") %in% names(fortify(n)))) ggplot(n, aes(x, y, xend = xend, yend = yend)) + diff --git a/tests/testthat/test-geoms.R b/tests/testthat/test-geoms.R index 459134b..4699e14 100644 --- a/tests/testthat/test-geoms.R +++ b/tests/testthat/test-geoms.R @@ -3,19 +3,27 @@ context("Test all geoms") data(emon, package = "network") test_that("geom_nodes works", { - ggplot(emon[[1]], aes(x, y)) + - geom_nodes() + expect_s3_class({ + ggplot(emon[[1]], aes(x, y)) + + geom_nodes() + }, class = "ggplot") - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_nodes() + expect_s3_class({ + ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + geom_nodes() + }, class = "ggplot") }) test_that("geom_nodetext works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_nodetext(aes(label = vertex.names)) + expect_s3_class({ + ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + geom_nodetext(aes(label = vertex.names)) + }, class = "ggplot") - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_nodetext(aes(label = Paid.Staff), nudge_x = 1, nudge_y = 1) + expect_s3_class({ + ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + geom_nodetext(aes(label = Paid.Staff), nudge_x = 1, nudge_y = 1) + }, class = "ggplot") expect_error( ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + @@ -28,16 +36,22 @@ test_that("geom_nodetext works", { }) test_that("geom_nodetext_repel works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_nodetext_repel(aes(label = vertex.names)) + expect_s3_class({ + ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + geom_nodetext_repel(aes(label = vertex.names)) + }, class = "ggplot") }) test_that("geom_nodelabel works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_nodelabel(aes(label = vertex.names)) + expect_s3_class({ + ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + geom_nodelabel(aes(label = vertex.names)) + }, class = "ggplot") - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_nodelabel(aes(label = Paid.Staff), nudge_x = 1, nudge_y = 1) + expect_s3_class({ + ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + geom_nodelabel(aes(label = Paid.Staff), nudge_x = 1, nudge_y = 1) + }, class = "ggplot") expect_error( ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + @@ -50,27 +64,37 @@ test_that("geom_nodelabel works", { }) test_that("geom_nodelabel_repel works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_nodelabel_repel(aes(label = vertex.names)) + expect_s3_class({ + ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + geom_nodelabel_repel(aes(label = vertex.names)) + }, class = "ggplot") }) test_that("geom_edges works", { # straight - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_edges() + expect_s3_class({ + ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + geom_edges() + }, class = "ggplot") # curved - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_edges(curvature = 0.1) + expect_s3_class({ + ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + geom_edges(curvature = 0.1) + }, class = "ggplot") }) test_that("geom_edgetext works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_edgetext(aes(label = Frequency)) + expect_s3_class({ + ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + geom_edgetext(aes(label = Frequency)) + }, class = "ggplot") - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_edgetext(aes(label = Frequency), nudge_x = 1, nudge_y = 1) + expect_s3_class({ + ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + geom_edgetext(aes(label = Frequency), nudge_x = 1, nudge_y = 1) + }, class = "ggplot") expect_error( ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + @@ -83,16 +107,22 @@ test_that("geom_edgetext works", { }) test_that("geom_edgelabel works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_edgelabel(aes(label = Frequency)) + expect_s3_class({ + ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + geom_edgelabel(aes(label = Frequency)) + }, class = "ggplot") }) test_that("geom_edgetext_repel works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_edgetext_repel(aes(label = Frequency)) + expect_s3_class({ + ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + geom_edgetext_repel(aes(label = Frequency)) + }, class = "ggplot") }) test_that("geom_edgelabel_repel works", { - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + - geom_edgelabel_repel(aes(label = Frequency)) + expect_s3_class({ + ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + geom_edgelabel_repel(aes(label = Frequency)) + }, class = "ggplot") }) diff --git a/tests/testthat/test-ggnetwork.R b/tests/testthat/test-ggnetwork.R index 4e37c46..8e4aecb 100644 --- a/tests/testthat/test-ggnetwork.R +++ b/tests/testthat/test-ggnetwork.R @@ -1,19 +1,22 @@ -context("Test ggnetwork") - -data(emon, package = "network") - test_that("ggnetwork works", { + data(emon, package = "network") expect_error(ggnetwork(-999, "could not coerce")) expect_error(ggnetwork(emon[[1]], layout = -999, "unsupported layout")) # facet by edge attribute - ggnetwork(emon[[1]], arrow.gap = 0.02, by = "Frequency") + expect_s3_class({ + ggnetwork(emon[[1]], arrow.gap = 0.02, by = "Frequency") + }, class = "data.frame") # user-provided layout - ggnetwork(emon[[1]], layout = matrix(runif(28), ncol = 2)) + expect_s3_class({ + ggnetwork(emon[[1]], layout = matrix(runif(28), ncol = 2)) + }, class = "data.frame") # edge weights in layout - ggnetwork(emon[[1]], layout = "kamadakawai", weights = "Frequency") + expect_s3_class({ + ggnetwork(emon[[1]], layout = "kamadakawai", weights = "Frequency") + }, class = "data.frame") # duplicated edges warning expect_warning( diff --git a/tests/testthat/test-utilities.R b/tests/testthat/test-utilities.R index f6c92b2..9eab209 100644 --- a/tests/testthat/test-utilities.R +++ b/tests/testthat/test-utilities.R @@ -1,15 +1,17 @@ -context("Test utilities") - test_that("theme_blank works", { - ggplot(ggnetwork(emon[[1]]), aes(x, y, xend = xend, yend = yend)) + - geom_edges() + - geom_nodes() + - theme_blank() + expect_s3_class({ + ggplot(ggnetwork(emon[[1]]), aes(x, y, xend = xend, yend = yend)) + + geom_edges() + + geom_nodes() + + theme_blank() + }, class = "ggplot") }) test_that("theme_facet works", { - ggplot(ggnetwork(emon[[1]]), aes(x, y, xend = xend, yend = yend)) + - geom_edges() + - geom_nodes() + - theme_facet() + expect_s3_class({ + ggplot(ggnetwork(emon[[1]]), aes(x, y, xend = xend, yend = yend)) + + geom_edges() + + geom_nodes() + + theme_facet() + }, class = "ggplot") }) From 13af180a437a6057fc00743386d4f31fdd5796af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 19:10:32 +0200 Subject: [PATCH 41/48] changelog update --- NEWS.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 77faef4..917b7ad 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,5 @@ ggnetwork 0.5.6 -============================ +=============== ## Repository changes @@ -22,6 +22,7 @@ ggnetwork 0.5.6 + update RoxygenNote version. + remove `ggplot2` from `Enhances` field. + add `Collate` field to load sequentially the functions. + + move `igraph` to `Imports` field. * Remove `inst/doc/` directory, *i.e.*, the vignette is part of the `pkgdown` website. @@ -30,6 +31,7 @@ ggnetwork 0.5.6 * In `R/fortify-igraph.R` and `R/fortify-network.R`, + use subsetting functions instead of `with` and `transform` (*i.e.*, intended to be use interactively). + fix issue from CRAN check with undefined global variables. + + remove namespace loading for `sna` package (*i.e.*, `gplot.layout.*` functions). * In `R/geom-nodes.R` and `R/geom-edges.R`, + remove unnecessary "@importFom". From 916bd80180fd9f3afeb08f1241858fd82df17808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 19:18:43 +0200 Subject: [PATCH 42/48] add ggplot2 prefix --- tests/testthat/test-fortify.R | 32 +++++++++++++++++--------------- tests/testthat/test-geoms.R | 12 ++++++------ tests/testthat/test-utilities.R | 4 ++-- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/tests/testthat/test-fortify.R b/tests/testthat/test-fortify.R index d03ad12..092d70f 100644 --- a/tests/testthat/test-fortify.R +++ b/tests/testthat/test-fortify.R @@ -1,22 +1,22 @@ test_that("fortify.network", { - data(flo, package = "network") + utils::data(flo, package = "network") n <- network::network(flo, directed = FALSE) expect_s3_class(fortify(n), "data.frame") expect_true(all(c("x", "y", "xend", "yend") %in% names(fortify(n)))) expect_s3_class({ - ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_nodes() + - geom_edges() + - geom_nodetext(aes(label = vertex.names)) + - geom_edgetext(aes(label = 1)) + - theme_blank() + ggplot2::ggplot(n, ggplot2::aes(x, y, xend = xend, yend = yend)) + + geom_nodes() + + geom_edges() + + geom_nodetext(aes(label = vertex.names)) + + geom_edgetext(aes(label = 1)) + + theme_blank() }, class = "ggplot") expect_s3_class({ - data(emon, package = "network") - ggplot(emon[[1]], aes(x = x, y = y, xend = xend, yend = yend)) + + utils::data(emon, package = "network") + ggplot2::ggplot(emon[[1]], ggplot2::aes(x = x, y = y, xend = xend, yend = yend)) + geom_edges() + geom_nodes(color = "tomato", size = 4) + theme_blank() @@ -29,10 +29,12 @@ test_that("fortify.igraph", { expect_s3_class(fortify(n), "data.frame") expect_true(all(c("x", "y", "xend", "yend") %in% names(fortify(n)))) - ggplot(n, aes(x, y, xend = xend, yend = yend)) + - geom_edges() + - geom_nodes() + - geom_nodetext(aes(label = name)) + - geom_edgetext(aes(label = 1)) + - theme_blank() + expect_s3_class({ + ggplot2::ggplot(n, ggplot2::aes(x, y, xend = xend, yend = yend)) + + geom_edges() + + geom_nodes() + + geom_nodetext(aes(label = name)) + + geom_edgetext(aes(label = 1)) + + theme_blank() + }, class = "ggplot") }) diff --git a/tests/testthat/test-geoms.R b/tests/testthat/test-geoms.R index 4699e14..76a20d2 100644 --- a/tests/testthat/test-geoms.R +++ b/tests/testthat/test-geoms.R @@ -87,17 +87,17 @@ test_that("geom_edges works", { test_that("geom_edgetext works", { expect_s3_class({ - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + ggplot2::ggplot(emon[[1]], ggplot2::aes(x, y, xend = xend, yend = yend)) + geom_edgetext(aes(label = Frequency)) }, class = "ggplot") expect_s3_class({ - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + ggplot2::ggplot(emon[[1]], ggplot2::aes(x, y, xend = xend, yend = yend)) + geom_edgetext(aes(label = Frequency), nudge_x = 1, nudge_y = 1) }, class = "ggplot") expect_error( - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + ggplot2::ggplot(emon[[1]], ggplot2::aes(x, y, xend = xend, yend = yend)) + geom_edgetext(aes(label = Frequency), nudge_x = 1, nudge_y = 1, position = "identity" @@ -108,21 +108,21 @@ test_that("geom_edgetext works", { test_that("geom_edgelabel works", { expect_s3_class({ - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + ggplot2::ggplot(emon[[1]], ggplot2::aes(x, y, xend = xend, yend = yend)) + geom_edgelabel(aes(label = Frequency)) }, class = "ggplot") }) test_that("geom_edgetext_repel works", { expect_s3_class({ - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + ggplot2::ggplot(emon[[1]], ggplot2::aes(x, y, xend = xend, yend = yend)) + geom_edgetext_repel(aes(label = Frequency)) }, class = "ggplot") }) test_that("geom_edgelabel_repel works", { expect_s3_class({ - ggplot(emon[[1]], aes(x, y, xend = xend, yend = yend)) + + ggplot2::ggplot(emon[[1]], ggplot2::aes(x, y, xend = xend, yend = yend)) + geom_edgelabel_repel(aes(label = Frequency)) }, class = "ggplot") }) diff --git a/tests/testthat/test-utilities.R b/tests/testthat/test-utilities.R index 9eab209..3deb10e 100644 --- a/tests/testthat/test-utilities.R +++ b/tests/testthat/test-utilities.R @@ -1,6 +1,6 @@ test_that("theme_blank works", { expect_s3_class({ - ggplot(ggnetwork(emon[[1]]), aes(x, y, xend = xend, yend = yend)) + + ggplot2::ggplot(ggnetwork(emon[[1]]), ggplot2::aes(x, y, xend = xend, yend = yend)) + geom_edges() + geom_nodes() + theme_blank() @@ -9,7 +9,7 @@ test_that("theme_blank works", { test_that("theme_facet works", { expect_s3_class({ - ggplot(ggnetwork(emon[[1]]), aes(x, y, xend = xend, yend = yend)) + + ggplot2::ggplot(ggnetwork(emon[[1]]), ggplot2::aes(x, y, xend = xend, yend = yend)) + geom_edges() + geom_nodes() + theme_facet() From 8c6cf4d067a9b17b8f54773aab992d16e2ae5a70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Fri, 19 Jul 2019 19:18:53 +0200 Subject: [PATCH 43/48] small change --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index bc31f6d..4ed4fb4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -17,8 +17,8 @@ License: GPL-3 URL: https://github.com/briatte/ggnetwork BugReports: https://github.com/briatte/ggnetwork/issues Depends: - ggplot2 (>= 2.0.0), R (>= 3.1), + ggplot2 (>= 2.0.0) Imports: ggrepel (>= 0.5), network, From 564c9a67648282fd60a9e6e3eb6fc5d841e2213c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Mon, 22 Jul 2019 12:41:11 +0200 Subject: [PATCH 44/48] fix typo --- README.Rmd | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.Rmd b/README.Rmd index e42e6cf..0d1c90c 100644 --- a/README.Rmd +++ b/README.Rmd @@ -69,7 +69,7 @@ Related packages: usethis::use_tidy_thanks() ``` -Thanks to two anonymous _[R Journal](https://journal.r-project.org/)_ reviewers.contributors, +Thanks to two anonymous _[R Journal](https://journal.r-project.org/)_ reviewers, [@achmurzy](https://github.com/achmurzy), [@andrewd789](https://github.com/andrewd789), [@ArtemSokolov](https://github.com/ArtemSokolov), [@aterhorst](https://github.com/aterhorst), [@briatte](https://github.com/briatte), [@emillykkejensen](https://github.com/emillykkejensen), [@evinhas](https://github.com/evinhas), [@FinScience](https://github.com/FinScience), [@ghost](https://github.com/ghost), [@instantkaffee](https://github.com/instantkaffee), [@jalapic](https://github.com/jalapic), [@jcfisher](https://github.com/jcfisher), [@jfaganUK](https://github.com/jfaganUK), [@kippjohnson](https://github.com/kippjohnson), [@koheiw](https://github.com/koheiw), [@mbojan](https://github.com/mbojan), [@mcanouil](https://github.com/mcanouil), [@mgagliol](https://github.com/mgagliol), [@mhairi](https://github.com/mhairi), [@minimaxir](https://github.com/minimaxir), [@mkarikom](https://github.com/mkarikom), [@nick-youngblut](https://github.com/nick-youngblut), [@SantiFilippo](https://github.com/SantiFilippo), [@sciabolazza](https://github.com/sciabolazza), [@sctyner](https://github.com/sctyner), [@trinker](https://github.com/trinker) and [@zachcp](https://github.com/zachcp) diff --git a/README.md b/README.md index 3c216d6..ce7d5d6 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ Related packages: ## Thanks Thanks to two anonymous *[R Journal](https://journal.r-project.org/)* -reviewers.contributors, [@achmurzy](https://github.com/achmurzy), +reviewers, [@achmurzy](https://github.com/achmurzy), [@andrewd789](https://github.com/andrewd789), [@ArtemSokolov](https://github.com/ArtemSokolov), [@aterhorst](https://github.com/aterhorst), From 4f1b1d0d36fd3ad9a43a89f2843f18a44c4f395d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Mon, 22 Jul 2019 15:39:00 +0200 Subject: [PATCH 45/48] safer approach to test layout dimension --- R/fortify-igraph.R | 6 +----- R/fortify-network.R | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/R/fortify-igraph.R b/R/fortify-igraph.R index 5ded135..6cf39ab 100644 --- a/R/fortify-igraph.R +++ b/R/fortify-igraph.R @@ -26,11 +26,7 @@ fortify.igraph <- function( ... ) { # node placement - if ( - class(layout) == "matrix" && - nrow(layout) == igraph::gorder(model) && - ncol(layout) == 2 - ) { + if (class(layout) == "matrix" && identical(dim(layout), c(igraph::gorder(model), 2L))) { nodes <- layout[, 1:2 ] } else { nodes <- igraph::layout_(model, layout, ...) diff --git a/R/fortify-network.R b/R/fortify-network.R index 29f01d9..f025953 100644 --- a/R/fortify-network.R +++ b/R/fortify-network.R @@ -118,11 +118,7 @@ fortify.network <- function( ... ) { # node placement - if ( - class(layout) == "matrix" && - nrow(layout) == network::network.size(model) && - ncol(layout) == 2 - ) { + if (class(layout) == "matrix" && identical(dim(layout), c(network::network.size(model), 2L))) { nodes <- layout[, 1:2 ] } else { layout <- eval(parse(text = paste0("sna::gplot.layout.", layout))) From 5f69008cc184b1e6e9b8ffe29bd4892fe1533af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Mon, 22 Jul 2019 15:42:51 +0200 Subject: [PATCH 46/48] replace if...else with a simple switch and tryCatch to handle errors --- NEWS.md | 2 ++ R/ggnetwork.R | 22 ++++++++++------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/NEWS.md b/NEWS.md index 917b7ad..2a657f1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -37,6 +37,8 @@ ggnetwork 0.5.6 + remove unnecessary "@importFom". + add missing function packages prefix. +* In `R/ggnetwork.R`, `switch` and `tryCatch` to make the `igraph` and `network` testing consistent. + * In `R/utilities.R`, reexport `fortify` and `unit` from `ggplot2`. diff --git a/R/ggnetwork.R b/R/ggnetwork.R index b489a6e..e80d777 100644 --- a/R/ggnetwork.R +++ b/R/ggnetwork.R @@ -16,17 +16,15 @@ #' #' @export ggnetwork <- function(x, ...) { - if (class(x) == "igraph") { - fortify.igraph(x, ...) - } else { - if (!network::is.network(x)) { - x <- try(network::network(x), silent = TRUE) + tryCatch( + switch( + EXPR = class(x), + "igraph" = fortify.igraph(x, ...), + "network" = fortify.network(x, ...), + fortify.network(network::network(x), ...) + ), + error = function(e) { + stop('could not coerce object to a "network"') } - - if (!network::is.network(x)) { - stop("could not coerce object to a network") - } else { - fortify.network(x, ...) - } - } + ) } From edd20a1afe45d18a252b7ad52795593fe6dff3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Mon, 22 Jul 2019 15:45:15 +0200 Subject: [PATCH 47/48] add missing reference to fortify.igraph --- R/ggnetwork.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/ggnetwork.R b/R/ggnetwork.R index e80d777..e0ff551 100644 --- a/R/ggnetwork.R +++ b/R/ggnetwork.R @@ -12,7 +12,7 @@ #' it will be used to convert the object: see #' \code{\link{fortify.igraph}} for details. #' -#' @param ... arguments passed to the \code{\link{fortify.network}} function. +#' @param ... arguments passed to the \code{\link{fortify.network}} or \code{\link{fortify.igraph}} function. #' #' @export ggnetwork <- function(x, ...) { From f3224f11dbce8817691bc10b68887ae8c950ec1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= Date: Mon, 22 Jul 2019 15:45:40 +0200 Subject: [PATCH 48/48] indent param description --- R/ggnetwork.R | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/R/ggnetwork.R b/R/ggnetwork.R index e0ff551..b6feeb0 100644 --- a/R/ggnetwork.R +++ b/R/ggnetwork.R @@ -3,14 +3,15 @@ #' A wrapper for the \code{\link{fortify.network}} and #' \code{\link{fortify.igraph}} functions that will also try to coerce matrices #' and data frames to network objects. +#' #' @param x an object of class \code{\link[network]{network}}, or any object -#' that can be coerced to this class, such as an adjacency or incidence matrix, -#' or an edge list: see \code{\link[network]{edgeset.constructors}} and -#' \code{\link[network]{network}} for details. If the object is of class -#' \code{\link[igraph:igraph-package]{igraph}} and the -#' \code{\link[intergraph:intergraph-package]{intergraph}} package is installed, -#' it will be used to convert the object: see -#' \code{\link{fortify.igraph}} for details. +#' that can be coerced to this class, such as an adjacency or incidence matrix, +#' or an edge list: see \code{\link[network]{edgeset.constructors}} and +#' \code{\link[network]{network}} for details. If the object is of class +#' \code{\link[igraph:igraph-package]{igraph}} and the +#' \code{\link[intergraph:intergraph-package]{intergraph}} package is installed, +#' it will be used to convert the object: see +#' \code{\link{fortify.igraph}} for details. #' #' @param ... arguments passed to the \code{\link{fortify.network}} or \code{\link{fortify.igraph}} function. #'