naniar icon indicating copy to clipboard operation
naniar copied to clipboard

geom_miss_point() [but not geom_point()] misaligned with errorbars

Open Aariq opened this issue 5 years ago • 2 comments

This is a weird one that took me a long time to reproduce. I'm making a plot with jittered points with errorbars (geom_errorbar, geom_linerange, and geom_errorbarh all have the following problem). I do the jitter with the position argument so the errobars and points match up. With geom_point(), the errorbars are correctly placed. But with geom_miss_point() the errorbars are misplaced, but only when the axis labels aren't in the same order as in the dataframe (I think??). Here's a reprex:

library(tidyverse)
library(naniar)

df1 <- tibble(y = rnorm(20, mean = 0, sd = 0.1),
              x = rep(c("a", "b", "c", "d", "e"), each = 4))

# different order for x
df2 <- tibble(y = rnorm(20, mean = 0, sd = 0.1),
              x = rep(c("e", "a", "b", "c", "d"), each = 4))

#set up jitter
j <- position_jitter(height = 0, width = 0.2)

# This works:
p <- ggplot(df2, aes(x, y)) +
  geom_point(position = j) +
  geom_linerange(aes(ymin = y - 0.5, ymax = y + 0.5), position = j)
p


# misaligned errorbars:
p_miss <- ggplot(df2, aes(x, y)) +
  geom_miss_point(position = j, jitter = 0) +
  geom_linerange(aes(ymin = y - 0.5, ymax = y + 0.5), position = j)
p_miss


# but this is fine for some reason:
p_miss2 <- ggplot(df1, aes(x, y)) + 
  geom_miss_point(position = j, jitter = 0) +
  geom_linerange(aes(ymin = y - 0.5, ymax = y + 0.5), position = j)
p_miss2


# I think it has to do with factor levels or something because this fixes the second plot.
df2 %>% 
  mutate(x = fct_inorder(x)) %>%
  ggplot(aes(x,y)) + 
  geom_miss_point(position = j, jitter = 0) +
  geom_linerange(aes(ymin = y - 0.5, ymax = y + 0.5), position = j)

Created on 2019-07-19 by the reprex package (v0.3.0)

Aariq avatar Jul 18 '19 19:07 Aariq

Yeah, I think it has to do with factor levels or something because this fixes the second plot.

df2 %>% 
  mutate(x = fct_inorder(x)) %>%
  ggplot(aes(x,y)) + 
  geom_miss_point(position = j, jitter = 0) +
  geom_linerange(aes(ymin = y - 0.5, ymax = y + 0.5), position = j)

Aariq avatar Jul 18 '19 19:07 Aariq

Thanks for posting an issue, and for taking the time to work out this tricky behaviour.

This is indeed some strange behaviour! Do you think you could copy/paste my code below into your initial comment? It contains a reprex with the images, which shows us more clearly what is going wrong here:

``` r
library(tidyverse)
library(naniar)

df1 <- tibble(y = rnorm(20, mean = 0, sd = 0.1),
              x = rep(c("a", "b", "c", "d", "e"), each = 4))

# different order for x
df2 <- tibble(y = rnorm(20, mean = 0, sd = 0.1),
              x = rep(c("e", "a", "b", "c", "d"), each = 4))

#set up jitter
j <- position_jitter(height = 0, width = 0.2)

# This works:
p <- ggplot(df2, aes(x, y)) +
  geom_point(position = j) +
  geom_linerange(aes(ymin = y - 0.5, ymax = y + 0.5), position = j)
p
```

![](https://i.imgur.com/aTKBcEn.png)

``` r

# misaligned errorbars:
p_miss <- ggplot(df2, aes(x, y)) +
  geom_miss_point(position = j, jitter = 0) +
  geom_linerange(aes(ymin = y - 0.5, ymax = y + 0.5), position = j)
p_miss
```

![](https://i.imgur.com/tGz0LZj.png)

``` r

# but this is fine for some reason:
p_miss2 <- ggplot(df1, aes(x, y)) + 
  geom_miss_point(position = j, jitter = 0) +
  geom_linerange(aes(ymin = y - 0.5, ymax = y + 0.5), position = j)
p_miss2
```

![](https://i.imgur.com/HIndl8Z.png)

``` r

# I think it has to do with factor levels or something because this fixes the second plot.
df2 %>% 
  mutate(x = fct_inorder(x)) %>%
  ggplot(aes(x,y)) + 
  geom_miss_point(position = j, jitter = 0) +
  geom_linerange(aes(ymin = y - 0.5, ymax = y + 0.5), position = j)
```

![](https://i.imgur.com/itH82np.png)

<sup>Created on 2019-07-19 by the [reprex package](https://reprex.tidyverse.org) (v0.3.0)</sup>

njtierney avatar Jul 19 '19 00:07 njtierney