jinworks/CellChat

Bug in ShinyApp Heatmap generation

WlabRW opened this issue · 0 comments

Thank you for developing this package.

I think I've identified a bug with the heatmap generation. If using the standard netVisual_heatmap() to generate a heatmap the results will not be consistent with whats generated by the heatmap in the ShinyApp interactive application accessed through runCellChatApp().
More specifically, the problem is that the the axes get swapped. Those considered "Source/Sender" by netVisual_heatmap() are swapped with the x-axis in the shinyApp. Although not wholly problematic, it does cause an inconsistency and makes the targets look like senders in the interactive app.
I've used the cellChat object data provided with the tutorial of the package "cellchat_humanSkin_LS.rds", though the inconsistency happens with my own personal data as well.

Note that the Sender "LC" here does not look as though it sends heavily weighted interactions to target "APOE+FIB".
OrignalCodeNonShinyApp
However if you look at Sender "LC" here it does look like the interaction weight is strong to "APOE+FIB". Looking at "LC" of the X-axis (presumably a target), you see the same pattern as in the non- ShinyApp instance of the code.
OriginalCodeShinyApp

Looking at runCellChatApp()'s code, it seems that this is due to incorrect conversion of the netVisual_heatmap() to a ggplot object that the ShinyApp uses. At line 66 of the app.R code:

  geom_tile(aes(row, column, fill = value),

Currently, in aes() the row and column are automatically stored in x and y respectively, however the rows in this case represent the y-axis of the heatmap matrix and the columns represent the x-axis of the heatmap matrix. Manually mapping these variables resolves the inconsistency in between the shinyapp plot and the core netVisual_heatmap() plot:

geom_tile(aes(y = row, x = column, fill = value),

Here the maps are now consistent.
RevisedShinyAppCode

I believe this is a bug, but perhaps there is something I'm misunderstanding with how the heatmap is interpreted.