Skip to content

rogerbeecham/odvis

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

odvis

R-CMD-check

odvis is an R package that provides helper functions for visualizing directed origin-destination data using ggplot2.

Installation

You can install the development version of odvis from GitHub with:

# install.packages("devtools")
devtools::install_github("rogerbeecham/odvis")

Asymmetric curves with get_trajectory()

Standard flow visualizations draw lines between origin-destination pairs. In ggplot2 this can be achieved by passing coordinates to geom_path(), one row for origin and destination respectively. In order to represent both outward and inward directions, we have to offset the locations (y-position) of the coordinate pairs.

od_pair <- tribble(
      ~direction, ~o_d,    ~x, ~y, 
       "out",        "origin",   0,  .2,   
       "out",        "destination",   1,  .2,
       "in",         "origin",   1,  -.2,
       "in",         "destination",   0,  -.2,
)      
     
od_pair |> 
  ggplot() +
  geom_point(aes(x=x, y=y*.2, group=direction, colour=direction)) +
  geom_path(aes(x=x, y=y*.2, group=direction, colour=direction)) +
  geom_text(aes(x=x, y=y*.5, label=o_d, colour=direction)) +
  geom_text(data=. %>% filter(o_d=="origin"), aes(x=.5, y=y, label=direction, colour=direction)) +
  scale_colour_manual(values=c("#b2182b", "#2166ac"), guide="none") +
  coord_equal(ylim=c(-.2, +.2), xlim=c(-.1, +1.1)) 

The ggforce extension provides a function for generating various curves, and we can use geom_bezier() to add a control point to offset curves depending on whether the direction is outward (bends upward) or inward (bends downward). This allows us to represent the origin and destination point locations in their exact position.

od_pair <- tribble(
      ~direction, ~o_d,    ~x, ~y, 
       "out",        "o",   0,  .015,   
       "out",        "c",   0.5,  .2, 
       "out",        "d",   1,.015,
       "in",         "o",   1,  -.015,
       "in",        "c",   0.5,  -.2, 
       "in",         "d",   0,  -.015,
)      
     
od_pair |> 
  ggplot() +
  geom_point(data=. %>% filter(o_d!="c"), aes(x=x, y=0, group=direction)) +
  geom_bezier0(aes(x=x, y=y, group=direction, colour=direction)) +
  geom_text(data=. %>% filter(o_d!="c"), 
            aes(x=x, y=y*3, label=o_d, colour=direction)) +
  geom_text(data=. %>% filter(o_d=="o"), aes(x=.5, y=y*12, label=direction, colour=direction)) +
  scale_colour_manual(values=c("#b2182b", "#2166ac"), guide="none") +
  coord_equal(ylim=c(-.2, +.2), xlim=c(-.1, +1.1))

A problem here is that the control point is not generalisable and the symbolisation not intuitive. The outward and inward directions are differentiated, but imagine a complex graph dataset with many edges in 2D space. So we move the control points such that lines curve towards the destination. This is achieved with get_trajectory(), which takes a character string naming the od-pair and locations in x and y of that OD’s origin an destination. The function returns a tibble of three rows representing origin, control point and destination respectively.

dat <- bind_rows(
  outward=get_trajectory(o_x=0,o_y=0,d_x=1,d_y=0, "out") |>
  add_column(type=c("o","c","d")), 
  inward=get_trajectory(o_x=1,o_y=0,d_x=0,d_y=0, "in") |> 
  add_column(type=c("o","c","d"))
  )

dat |> 
  ggplot(aes(x=x,y=y, colour=od_pair)) +
  geom_point(data=. %>% filter(type!="c"), colour="#252525") +
  ggforce::geom_bezier0(aes(group=od_pair)) +
   geom_text(data=. %>% filter(type=="c"), aes(label=od_pair)) +
  scale_colour_manual(values=c("#b2182b", "#2166ac"), guide="none") +
  coord_equal() 

Example

OD Maps

About

Parameterising ggplot2 Graphics for Origin-Destination Visualization

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages