Trader physics Trader physics - 1 month ago 12
R Question

geom_tile finding the proper height of tiles

I am plotting a heatmap with

ggplot(param, aes(V2, V1,z=V7))+ geom_tile(aes(fill = V7, height=0.02))


But my V1 is not equally spaced. How can I find the proper height? Beacause height=0.02 might be too large for some small value, so that they are covered by other.

Can you give me an example how to do that? E.g. The V1 value are like:

1, 0.8,0.7,0.45,0.3, 0.12,0.07,0.0004

So i need to find the differences of each pair of values. But the min height is different to the max height. I read that the tile is going from -h/2 to h/2 for height h. But the min height is of course different to avoid gaps!

Answer

The answer depends (heavily) on what you are trying to represent. If there is some inherent height (e.g, the range over which the value should apply) you should use that. That is, if each measure is a point measure over a small area, that is the area that should be used.

If, however, all you want to do is make the bars touch each other, that can be done, but will have to be done outside the call to ggplot. (Note also: the interpretation of your graph may be off a bit, as larger gaps will imply that some measures cover wider areas than others, and those bars will not be centered on the true location.)

Using dplyr you can simply calculate the midpoint between two measurements and use that as the boundary between your points. Then, use geom_rect instead of geom_tile to pass in those boundaries directly. Note that this assumes some things about your range of values since you did not post any data:

sampleData <-
  data.frame(
    x = c(1,2,3)
    , y = c(0.01, 0.1, 1)
    , z = c(1,2,3)
  )


sampleData %>%
  mutate(ymin = (y + lag(y, default = 0))/2
         , ymax = (y + lead(y, default = 1.5))/2
         , xmin = x - 0.5
         , xmax = x + 0.5
         ) %>%
  ggplot(aes(xmin = xmin
             , xmax = xmax
             , ymin = ymin
             , ymax = ymax
             , fill = z)) +
  geom_rect()

enter image description here

Here is an example using multiple x locations. Note that here, instead of averaging to get the ymin and ymax, I explicitly set them to the edges I want:

sampleData <-
  data.frame(
    x = rep(c(1,2,3), each = 3)
    , y = c(0.01, 0.1, 1
            , 0.04, 0.3, 0.9
            , 0.2, 0.5, 0.8)
    , z = c(1,2,3)
  )


sampleData %>%
  group_by(x) %>%
  arrange(y) %>%
  mutate(ymin = (y + lag(y))/2
         , ymax = (y + lead(y))/2
         , xmin = x - 0.5
         , xmax = x + 0.5
         , ymin = ifelse(is.na(ymin), 0, ymin)
         , ymax = ifelse(is.na(ymax), 1.25, ymax)
  ) %>%
  ggplot(aes(xmin = xmin
             , xmax = xmax
             , ymin = ymin
             , ymax = ymax
             , fill = z)) +
  geom_rect()

enter image description here

Comments