Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Line made of small arrows for R plot [duplicate]

Tags:

plot

r

I would like to define a custom line type for a graph in R.

As a minimal working example, consider the following

plot(1:5,runif(5),type="l",lty="longdash")

which gives me just some random line (like the dashed black line in the picture below). Is there a way to instead make the dashes look like small arrows (like in the red example, which I constructed with illustrator)?

enter image description here

like image 575
mimuller Avatar asked Mar 03 '23 18:03

mimuller


2 Answers

I continued on the work of @cardinal40. The added value is that in my solution, there is space between the consecutive arrows.

df2 %>% 
  left_join(df, by = "x") %>% 
  mutate(
    y = if_else(is.na(y), approx(x, y, x)$y, y),

    ## calculate the change in x and y, and take 20%
    x_delta = abs(x-lead(x))*.2,
    y_delta = abs(y -lead(y))*.2,

    ### provide the relative space calculate above but ... 
    ### treat differently depending on descending or ascending
    xend = ifelse(x > lead(x), lead(x)+x_delta, lead(x)-x_delta),
    yend = ifelse(y > lead(y), lead(y)+y_delta, lead(y)-y_delta)

  ) %>% 
  filter(!is.na(xend)) %>% 
  ggplot(aes(x = x, y = y, xend = xend, yend = yend)) +
  geom_segment(arrow = arrow(length = unit(0.1, "inches")))

This yields the following graph:

enter image description here

like image 170
KoenV Avatar answered Mar 05 '23 16:03

KoenV


library(tidyverse)
set.seed(1)

# Original data
df <- tibble(x = 1:5, y = runif(5))

# Intermediate points
df2 <- tibble(x = seq(min(df$x), max(df$x), by = 0.25))

# Join, interpolate and plot
df2 %>% 
  left_join(df, by = "x") %>% 
  mutate(
    y = if_else(is.na(y), approx(x, y, x)$y, y),
    xend = lead(x),
    yend = lead(y)
  ) %>% 
  filter(!is.na(xend)) %>% 
  ggplot(aes(x = x, y = y, xend = xend, yend = yend)) +
  geom_segment(arrow = arrow(length = unit(0.1, "inches")))

The gaps between the arrows are a complicating factor but this overall setup could be a good starting point.

enter image description here

like image 36
cardinal40 Avatar answered Mar 05 '23 14:03

cardinal40