1

I am trying to make a heatmap that displays a histogram over 100 days. My data looks as follows:

>head(dat_from_hist)

    0 1  2  3  4  5  6  7 8 9 10 11 12 13 14
[1,] 2 3 11 20 16 17 13 10 6 1  1  1  0  0  0
[2,] 2 3 12 26 18 19  7  6 4 3  1  1  0  0  0
[3,] 0 6  8 16 18 15 11 13 7 4  2  1  0  0  0
[4,] 1 6 12 13 14 19 15 12 7 3  3  1  0  0  0
[5,] 1 2 10 17 23 16 14 10 3 3  2  1  0  0  0
[6,] 1 9 11 16 17 18  6 11 4 6  2  0  1  0  0

In this matrix, the columns represent the frequency (number of contacts on a day) and the rows represent the days. Now in principle, the data in this matrix is already ordered as I want it, and I simply want to represent it using a heatmap/tile plot.

I have tried to plot it with ggplot2 geom_raster(), using the following code:

dat_from_hist %>% 
  as.data.frame() %>%
  rownames_to_column("Day") %>%
  pivot_longer(-c(Day), names_to = "contacts", values_to = "counts") %>%
  ggplot(aes(x=contacts, y=Day, fill=counts)) + 
  geom_tile() +
  scale_fill_viridis_c()

However, plotting it like this results in the following plot (as this is my first post, it has to be posted via link): histogram of contacts over time

The main problem is that the days and contacts axes are reordered alphabetically, where I want the numerical orders for both axes ([1,2,3,...] instead of [1,10,11,...]). Besides this problem, the plot is exactly how I want it.

I have tried multiple other heatmaps/tile plotters, but this one seems so close that there must be a way to fix it. For geom_raster I have tried using sort() and order(). Does anyone know how to fix this and plot the matrix into a heatmap without any reordering of columns/rows?

Any help is greatly appreciated

  • Convert you `contacts` column to a numeric after `pivot_longer`. You could also do that using `pivot_longer(... , names_transform = list(contacts = as.numeric)`. And of course you probably have to do that also the value column. – stefan Dec 16 '21 at 13:27

1 Answers1

0
dat_from_hist %>% 
  as.data.frame() %>%
  rownames_to_column("Day") %>%
  pivot_longer(-c(Day), names_to = "contacts", values_to = "counts") %>%
  ggplot(aes(x=as.numeric(contacts), y=as.numeric(Day), fill=counts)) + 
  geom_tile() +
  scale_fill_viridis_c()

Adding as.numeric fixed it indeed! thanks