通过在一个框中包装点来注释ggplot2

时间:2018-06-09 15:05:27

标签: r ggplot2

我有一个看起来像这样的图(下面生成它的代码):

Movement of bits using one-at-a-time-hashing

我想知道是否有一种简单的方法可以让它看起来像这样:

Highlighted input bytes

即,我想通过在它们周围放一个方框来突出显示四行中的八个位置。

如果您感兴趣,该图显示了四个字节上使用一次一个哈希函数的位如何移动,所以我想突出显示四个输入字节。我在各种其他图中叠加了不同的位模式,显示了不同的位如何依赖于函数参数中的其他位和输入位。所以我必须生成相同绘图的几个版本,因此我更不希望为每个绘图注释PDF文件。

library(dplyr)
library(purrr)
library(ggplot2)

oaat_hash_positions <- function(bit) {
  op_1 <- function(pos, step, bit) {
    updated_pos <- outer(pos, c(10, 0), FUN = '+')  %>% as.vector() %>% unique()
    tibble(bit = bit, x = step - 1, y = pos, xend = step, yend = updated_pos) %>%
      filter(y >= 0 & y < 32 & yend >= 0 & yend < 31)
  }
  op_2 <- function(pos, step, bit) {
    updated_pos <- outer(pos, c(0, -6), FUN = '+')  %>% as.vector() %>% unique()
    tibble(bit = bit, x = step - 1, y = pos, xend = step, yend = updated_pos) %>%
      filter(y >= 0 & y < 32 & yend >= 0 & yend < 31)
  }
  final_op_1 <- function(pos, step, bit) {
    updated_pos <- outer(pos, c(0, 3), FUN = '+')  %>% as.vector() %>% unique()
    tibble(bit = bit, x = step - 1, y = pos, xend = step, yend = updated_pos) %>%
      filter(y >= 0 & y < 32 & yend >= 0 & yend < 31)
  }
  final_op_2 <- function(pos, step, bit) {
    updated_pos <- outer(pos, c(0, -11), FUN = '+')  %>% as.vector() %>% unique()
    tibble(bit = bit, x = step - 1, y = pos, xend = step, yend = updated_pos) %>%
      filter(y >= 0 & y < 32 & yend >= 0 & yend < 31)
  }
  final_op_3 <- function(pos, step, bit) {
    updated_pos <- outer(pos, c(0, 15), FUN = '+')  %>% as.vector() %>% unique()
    tibble(bit = bit, x = step - 1, y = pos, xend = step, yend = updated_pos) %>%
      filter(y >= 0 & y < 32 & yend >= 0 & yend < 31)
  }

  operation_1 <- map(bit,              ~ op_1(.x, step = 1, bit = bit)) %>% bind_rows()
  operation_2 <- map(operation_1$yend, ~ op_2(.x, step = 2, bit = bit)) %>% bind_rows()
  operation_3 <- map(operation_2$yend, ~ op_1(.x, step = 3, bit = bit)) %>% bind_rows()
  operation_4 <- map(operation_3$yend, ~ op_2(.x, step = 4, bit = bit)) %>% bind_rows()
  operation_5 <- map(operation_4$yend, ~ op_1(.x, step = 5, bit = bit)) %>% bind_rows()
  operation_6 <- map(operation_5$yend, ~ op_2(.x, step = 6, bit = bit)) %>% bind_rows()
  operation_7 <- map(operation_6$yend, ~ op_1(.x, step = 7, bit = bit)) %>% bind_rows()
  operation_8 <- map(operation_7$yend, ~ op_2(.x, step = 8, bit = bit)) %>% bind_rows()

  operation_9 <-  map(operation_8$yend,  ~ final_op_1(.x, step = 9, bit = bit)) %>% bind_rows()
  operation_10 <- map(operation_9$yend,  ~ final_op_2(.x, step = 10, bit = bit)) %>% bind_rows()
  operation_11 <- map(operation_10$yend, ~ final_op_3(.x, step = 11, bit = bit)) %>% bind_rows()

  rbind(operation_1, operation_2,
        operation_3, operation_4,
        operation_5, operation_6,
        operation_7, operation_8,
        operation_9, operation_10, operation_11)
}
bit_movement <- do.call(rbind, lapply(0:31, oaat_hash_positions))

plot_bitmovement <- function(bm_segs) {
  ggplot(bm_segs, aes(
    x = x,
    y = y,
    xend = xend,
    yend = yend)
  ) +
    geom_segment(colour = "grey") +
    geom_point(colour = "grey") +
    geom_point(aes(x = xend, y = yend), colour = "grey") +
    coord_flip() +
    scale_y_reverse(breaks = 0:31, labels = 1:32) +
    scale_x_reverse() +
    theme_minimal() +
    theme(
      legend.position = "none"
    ) + ylab("Bit-position") + xlab("Operation")
}

plot_bitmovement(bit_movement)

1 个答案:

答案 0 :(得分:3)

您可以添加一个没有填充的geom_rect来围绕这些点放置边框。我不熟悉您正在处理的环境,因此您可能需要在此处调整一些内容。我在函数中添加了参数,因此您可以提供一个操作值向量和要突出显示的位置,以及在框中放置多少填充值。

我没有解决这样一个事实,即你的休息时间和标签被1个偏移,就像我说的那样,这可能是你想要解决的特定情境。

library(tidyverse)

# omitting function that creates bitmovement data

plot_bitmovement <- function(bm_segs, hilite_op, hilite_pos, box_pad = 0.4) {
  hilite <- tibble(x = hilite_op, ymin = min(hilite_pos), ymax = max(hilite_pos))

  ggplot(bm_segs, aes(
    x = x,
    y = y,
    xend = xend,
    yend = yend)
  ) +
    geom_segment(colour = "grey") +
    geom_point(colour = "grey") +
    geom_point(aes(x = xend, y = yend), colour = "grey") +
  # add hilite box #########
    geom_rect(aes(xmin = x - box_pad, 
                  xmax = x + box_pad, 
                  ymin = ymin - box_pad, 
                  ymax = ymax + box_pad), 
              data = hilite, color = "black", fill = "transparent", inherit.aes = F) +
  ##########################
    coord_flip() +
    scale_y_reverse(breaks = 0:31, labels = 1:32) +
    scale_x_reverse() +
    theme_minimal() +
    theme(
      legend.position = "none"
    ) + ylab("Bit-position") + xlab("Operation")
}

hilite_x <- seq(0, 6, by = 2)
hilite_y <- 1:8

plot_bitmovement(bit_movement, hilite_x, hilite_y)

reprex package(v0.2.0)创建于2018-06-09。