saeyslab / multinichenetr

MultiNicheNet: a flexible framework for differential cell-cell communication analysis from multi-sample multi-condition single-cell transcriptomics data
GNU General Public License v3.0
112 stars 14 forks source link

Error calling graph_plot$plot #10

Closed SergioRodLla closed 10 months ago

SergioRodLla commented 1 year ago

Hi @browaeysrobin,

I am trying to generate the Intercellular regulatory network systems view you include at the end of the basic analysis vignette. When I call graph_plot$plot I get the following error:

Error in ggraph::geom_edge_loop(aes(color = direction_regulation), edge_width = 1, :

ℹ Error occurred in the 2nd layer.
Caused by error in `seq_len()`:
! argument must be coercible to non-negative integer
27. stop(fallback)
26. signal_abort(cnd, .file)
25. rlang::abort(message, ..., call = call, use_cli_format = TRUE,
.frame = .frame)
24. cli::cli_abort(c("Problem while {step}.", i = "Error occurred in the {ordinal(i)} layer."),
call = layers[[i]]$constructor, parent = cnd)
23. handlers[[1L]](cnd)
22. h(simpleError(msg, call))
21. .handleSimpleError(function (cnd)
{
{
.__handler_frame__. <- TRUE ...
20. split_with_index(seq_len(nrow(df)), ids)
19. dapply(data, "PANEL", function(data) {
scales <- layout$get_scales(data$PANEL[1])
try_fetch(inject(self$compute_panel(data = data, scales = scales,
!!!params)), error = function(cnd) { ...
18. compute_layer(..., self = self)
17. self$stat$compute_layer(data, self$computed_stat_params, layout)
16. compute_statistic(..., self = self)
15. l$compute_statistic(d, layout)
14. f(l = layers[[i]], d = data[[i]])
13. withCallingHandlers(expr, condition = function(cnd) {
{
.__handler_frame__. <- TRUE
.__setup_frame__. <- frame ...
12. doTryCatch(return(expr), name, parentenv, handler)
11. tryCatchOne(expr, names, parentenv, handlers[[1L]])
10. tryCatchList(expr, classes, parentenv, handlers)
9. tryCatch(withCallingHandlers(expr, condition = function(cnd) {
{
.__handler_frame__. <- TRUE
.__setup_frame__. <- frame ...
8. try_fetch(for (i in seq_along(data)) {
out[[i]] <- f(l = layers[[i]], d = data[[i]])
}, error = function(cnd) {
cli::cli_abort(c("Problem while {step}.", i = "Error occurred in the {ordinal(i)} layer."), ...
7. by_layer(function(l, d) l$compute_statistic(d, layout), layers,
data, "computing stat")
6. ggplot_build.ggplot(x)
5. NextMethod()
4. ggplot_build.ggraph(x)
3. ggplot_build(x)
2. print.ggplot(x)
1. (function (x, ...)
UseMethod("print"))(x)

Thank you again for the help!

Sergio

n318162971 commented 1 year ago

Same problem for me, running rlang::last_trace() gives:

<error/rlang_error>
Error in `ggraph::geom_edge_loop()`:
! Problem while computing stat.
ℹ Error occurred in the 2nd layer.
Caused by error in `seq_len()`:
! argument must be coercible to non-negative integer
---
Backtrace:
     ▆
  1. ├─base (local) `<fn>`(x)
  2. └─ggplot2:::print.ggplot(x)
  3.   ├─ggplot2::ggplot_build(x)
  4.   ├─ggraph:::ggplot_build.ggraph(x)
  5.   ├─base::NextMethod()
  6.   └─ggplot2:::ggplot_build.ggplot(x)
  7.     └─ggplot2:::by_layer(...)
  8.       ├─rlang::try_fetch(...)
  9.       │ ├─base::tryCatch(...)
 10.       │ │ └─base (local) tryCatchList(expr, classes, parentenv, handlers)
 11.       │ │   └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
 12.       │ │     └─base (local) doTryCatch(return(expr), name, parentenv, handler)
 13.       │ └─base::withCallingHandlers(...)
 14.       └─ggplot2 (local) f(l = layers[[i]], d = data[[i]])
 15.         └─l$compute_statistic(d, layout)
 16.           └─ggplot2 (local) compute_statistic(..., self = self)
 17.             └─self$stat$compute_layer(data, self$computed_stat_params, layout)
 18.               └─ggplot2 (local) compute_layer(..., self = self)
 19.                 └─ggplot2:::dapply(...)
 20.                   └─ggplot2:::split_with_index(seq_len(nrow(df)), ids)
browaeysrobin commented 1 year ago

Hi @SergioRodLla and @n318162971

Could you provide some more useful information about your specific analyses, otherwise I won't be able to help you because this plotting function works still fine for me on the vignette datasets and other datasets.

SergioRodLla commented 1 year ago

Hi, thank you for the reply.

Answering your questions, yes, I encountered this error on my own data. I followed this vignette basic_analysis_steps_MISC.md. The only warning I encountered was this when generating the lr_target_prior_cor_filtered table:

Joining with `by = join_by(receiver, ligand, target)`Warning: Detected an unexpected many-to-many relationship between `x` and `y`.Joining with `by = join_by(contrast)`

Details about this experiment include running two sender cell-types (A & B) and two receiver cell-types (C & D), comparing two conditions of interest (two different diets). Note: I run the same steps excluding one of the two sender cell-types and it worked. I compared the lr_target_prior_cor_filtered, prioritized_tbl_oi and colors_sender objects between these two tests and they have the same structure, with the same columns and so on. I'm not sure what to look at here.

browaeysrobin commented 1 year ago

Hi @SergioRodLla

I have no idea what might be going on there. Can you try to debug yourself to see where exactly in the function the error occurs? In case you are not familiar with doing this, I can do this if you would send me (by mail) 1) the input objects of the make_ggraph_ligand_target_links when the error is thrown and 2) the input objects when it runs without problems.

mariecrane commented 1 year ago

I'm encountering the same error. @SergioRodLla could you please update if you find a solution?

SergioRodLla commented 1 year ago

Hi @browaeysrobin I've sent you an email with the data. I hope this helps.

browaeysrobin commented 10 months ago

Hi @SergioRodLla @mariecrane @n318162971

I think I identified the issue, which seems to arise from a bug in the underlying ggraph::geom_edge_loop function. When there are no self-loops in the network, this gave an error on my test data.

We are currently improving the code on this, and several other aspects, which will be released soon in version 2 (currently on dev-branch, later on main branch once all new vignettes and code will be ensured to be compatible).

For the moment, using the following function should work.

make_ggraph_ligand_target_links = function(lr_target_prior_cor_filtered, prioritized_tbl_oi, colors){

  requireNamespace("dplyr")
  requireNamespace("ggplot2")
  requireNamespace("ggraph")

  lr_target_prior_cor_filtered = lr_target_prior_cor_filtered %>% dplyr::inner_join(prioritized_tbl_oi, by = c("sender", "receiver", "ligand", "receptor", "id", "group"))

  source_df_lr = prioritized_tbl_oi %>% dplyr::mutate(celltype_ligand = paste(sender, ligand, sep = "_"), celltype_receptor = paste(receiver, receptor, sep = "_")) %>% dplyr::select(group, sender, receiver, celltype_ligand, celltype_receptor, ligand, receptor) 
  source_df_lrt = lr_target_prior_cor_filtered %>% dplyr::mutate(celltype_ligand = paste(sender, ligand, sep = "_"), celltype_target = paste(receiver, target, sep = "_"), celltype_receptor = paste(receiver, receptor, sep = "_")) %>% dplyr::select(group, sender, receiver, celltype_ligand, celltype_receptor, celltype_target, ligand, target, receptor, direction_regulation) 

  lr_gr_network = dplyr::bind_rows(
    source_df_lrt %>% dplyr::filter(celltype_target %in% source_df_lr$celltype_ligand & !celltype_target %in% source_df_lr$celltype_receptor) %>% dplyr::mutate(type_target = "ligand"),
    source_df_lrt %>% dplyr::filter(celltype_target %in% source_df_lr$celltype_receptor  & !celltype_target %in% source_df_lr$celltype_ligand) %>% dplyr::mutate(type_target = "receptor")
  ) %>% dplyr::bind_rows(
    source_df_lrt %>% dplyr::filter(celltype_target %in% source_df_lr$celltype_ligand & celltype_target %in% source_df_lr$celltype_receptor) %>% dplyr::mutate(type_target = "ligand/receptor")
  )

  ligand_receptor_network = lr_gr_network %>% dplyr::filter(celltype_receptor %in% celltype_target) %>% dplyr::select(celltype_ligand, celltype_receptor, direction_regulation, group) %>% dplyr::distinct() %>% dplyr::rename(sender = celltype_ligand, receiver = celltype_receptor) %>% dplyr::mutate(type = "Ligand-Receptor", weight = 1)

  ligand_target_network = lr_gr_network %>% dplyr::select(celltype_ligand, celltype_target, direction_regulation, group) %>% dplyr::distinct() %>% dplyr::rename(sender = celltype_ligand, receiver = celltype_target) %>% dplyr::mutate(type = "Ligand-Target", weight = 1)

  links = ligand_target_network %>% dplyr::bind_rows(ligand_receptor_network) 
  nodes = lr_gr_network %>% dplyr::select(celltype_ligand, sender, ligand) %>% dplyr::rename(celltype = sender, node = celltype_ligand, gene = ligand) %>% dplyr::mutate(type_gene = "ligand") %>% dplyr::bind_rows(
    lr_gr_network %>% dplyr::select(celltype_receptor, receiver, receptor) %>% dplyr::rename(celltype = receiver, node = celltype_receptor, gene = receptor) %>% dplyr::mutate(type_gene = "receptor")
  ) %>% dplyr::bind_rows(
    lr_gr_network %>% dplyr::select(celltype_target, receiver, target, type_target) %>% dplyr::rename(celltype = receiver, node = celltype_target, gene = target, type_gene = type_target)
  ) %>% dplyr::distinct() %>% dplyr::filter(node %in% c(links$sender, links$receiver))

  double_nodes =  nodes %>% dplyr::group_by(node) %>% dplyr::count() %>% dplyr::filter(n > 1) %>% pull(node)
  nodes = dplyr::bind_rows(
    nodes %>% dplyr::filter(node %in% double_nodes) %>% dplyr::mutate(type_gene = "ligand/receptor") ,
    nodes %>% dplyr::filter(!node %in% double_nodes)
  ) %>% dplyr:: distinct()

  nodes = nodes %>% data.frame() %>% magrittr::set_rownames(nodes$node)

  colors_regulation = NULL
  colors_regulation["up"] = "indianred1"
  colors_regulation["down"] = "steelblue2"

  # create the network object
  network = igraph::graph_from_data_frame(d=links %>% dplyr::filter(type == "Ligand-Target"), vertices = nodes, directed=T)
  graph = tidygraph::as_tbl_graph(network) 
  set.seed(1919)
  plot =  ggraph::ggraph(graph, layout = 'dh') + 
    ggraph::geom_edge_fan(aes(color = direction_regulation), edge_width = 1, arrow = arrow(length = unit(3, 'mm')), end_cap = ggraph::circle(5.5, 'mm'), start_cap = ggraph::circle(3, 'mm')) + 
    # ggraph::geom_edge_loop(aes(color = direction_regulation), edge_width = 1, alpha = 0.70)  + 
    ggraph::geom_node_label(aes(label = gene, fill = celltype), fontface = "bold", size = 3.5, nudge_x = 0, nudge_y = 0, color = "whitesmoke") +
    ggraph::theme_graph(foreground = 'black', fg_text_colour = 'white', base_family = 'Helvetica') + facet_grid(. ~group)  + ggraph::scale_edge_color_manual(values = colors_regulation) + scale_fill_manual(values = colors)

  return(list(plot = plot, graph = graph, source_df_lr = source_df_lr, source_df_lt = links %>% dplyr::filter(type == "Ligand-Target"), nodes_df = nodes))
}

Please let me know if you would still have issues with this. If none of you encounter further issues, I will close this issue from the moment we release the next version of the package where this should be fixed.

SergioRodLla commented 10 months ago

It's working for me thanks!