11# ' Cell Dimension Reduction Plot
22# '
33# ' @description This function creates a dimension reduction plot for a Seurat object
4- # ' or a Giotto object. It allows for various customizations such as grouping by metadata,
4+ # ' a Giotto object, a path to an .h5ad file or an opened `H5File` by `hdf5r` package.
5+ # ' It allows for various customizations such as grouping by metadata,
56# ' adding edges between cell neighbors, highlighting specific cells, and more.
67# ' This function is a wrapper around [plotthis::DimPlot()], which provides a
78# ' flexible way to visualize cell clusters in reduced dimensions. This function
89# ' extracts the necessary data from the Seurat or Giotto object and passes it to
910# ' [plotthis::DimPlot()].
10- # ' @param object A seurat object or a giotto object.
11+ # ' @param object A seurat object, a giotto object, a path to an .h5ad file or an opened `H5File` by `hdf5r` package .
1112# ' @param reduction Name of the reduction to plot (for example, "umap").
1213# ' @param graph Specify the graph name to add edges between cell neighbors to the plot.
1314# ' @param velocity The name of velocity reduction to plot cell velocities.
3031# ' * <https://pwwang.github.io/scplotter/articles/Giotto_Visium.html>
3132# ' * <https://pwwang.github.io/scplotter/articles/Giotto_VisiumHD.html>
3233# ' * <https://pwwang.github.io/scplotter/articles/Giotto_Xenium.html>
34+ # '
3335# ' for examples of using this function with a Giotto object.
36+ # '
37+ # ' And see:
38+ # ' * <https://pwwang.github.io/scplotter/articles/Working_with_anndata_h5ad_files.html>
39+ # '
40+ # ' for examples of using this function with .h5ad files.
3441# ' @examples
3542# ' \donttest{
3643# ' data(pancreas_sub)
@@ -157,7 +164,7 @@ CellDimPlot.giotto <- function(
157164 object , reduction = NULL , graph = NULL , group_by = NULL ,
158165 spat_unit = NULL , feat_type = NULL , velocity = NULL , ...
159166) {
160- stopifnot(" [CellDimPlot] 'group_by' is required." = ! is.null(group_by ))
167+ stopifnot(" [CellDimPlot] 'group_by' is required for giotto objects ." = ! is.null(group_by ))
161168
162169 spat_unit <- GiottoClass :: set_default_spat_unit(
163170 gobject = object ,
@@ -271,16 +278,84 @@ CellDimPlot.Seurat <- function(
271278 DimPlot(data , graph = graph , group_by = group_by , velocity = velocity , ... )
272279}
273280
281+ # ' @export
282+ CellDimPlot.character <- function (
283+ object , reduction = NULL , graph = NULL , group_by = NULL ,
284+ spat_unit = NULL , feat_type = NULL , velocity = NULL ,
285+ ...
286+ ) {
287+ if (! endsWith(object , " .h5ad" )) {
288+ stop(" [CellDimPlot] Currently only supports .h5ad files when called with a string/path." )
289+ }
290+
291+ object <- hdf5r :: H5File $ new(object , mode = " r" )
292+ on.exit(object $ close_all())
293+
294+ CellDimPlot.H5File(
295+ object = object , reduction = reduction , graph = graph ,
296+ group_by = group_by , spat_unit = spat_unit , feat_type = feat_type ,
297+ velocity = velocity , ...
298+ )
299+ }
300+
301+ # ' @export
302+ CellDimPlot.H5File <- function (
303+ object , reduction = NULL , graph = NULL , group_by = NULL ,
304+ spat_unit = NULL , feat_type = NULL , velocity = NULL ,
305+ ...
306+ ) {
307+ stopifnot(" [CellDimPlot] 'spat_unit' and 'feat_type' are not used for anndata." =
308+ is.null(spat_unit ) && is.null(feat_type ))
309+ stopifnot(" [CellDimPlot] 'group_by' is required for anndata (h5ad) objects." = ! is.null(group_by ))
310+
311+ reductions <- names(object [[' obsm' ]])
312+ if (is.null(reductions ) || length(reductions ) == 0 ) {
313+ stop(" [CellDimPlot] The object does not have any reductions." )
314+ }
315+
316+ reduction <- reduction %|| % reductions [1 ]
317+ if (! startsWith(reduction , " X_" ) && ! reduction %in% reductions ) {
318+ reduction <- paste0(" X_" , reduction )
319+ }
320+
321+ if (! reduction %in% reductions ) {
322+ stop(" [CellDimPlot] The object does not have reduction:" , reduction )
323+ }
324+
325+ if (! is.null(graph )) {
326+ ggrp <- object [[' obsp' ]][[' connectivities' ]]
327+ if (is.null(ggrp )) {
328+ stop(" [CellDimPlot] The object does not have any graph/connectivities." )
329+ }
330+
331+ graph <- h5group_to_matrix(ggrp )
332+ graph <- igraph :: graph_from_adjacency_matrix(graph , mode = " undirected" , weighted = TRUE )
333+ graph <- igraph :: as_adjacency_matrix(graph , attr = " weight" , sparse = TRUE )
334+ colnames(graph ) <- rownames(graph ) <- object [[' obs' ]][[' index' ]]$ read()
335+ }
336+
337+ data <- cbind(t(object [[" obsm" ]][[reduction ]]$ read()), h5group_to_dataframe(object [[' obs' ]]))
338+ rownames(data ) <- object [[' obs' ]][[' index' ]]$ read()
339+
340+ if (! is.null(velocity )) {
341+ velocity <- t(object [[" obsm" ]][[velocity ]]$ read())
342+ }
343+
344+ DimPlot(data , graph = graph , group_by = group_by , velocity = velocity , ... )
345+ }
346+
347+
274348# ' Cell Velocity Plot
275349# '
276- # ' @description This function creates a cell velocity plot for a Seurat object
277- # ' or a Giotto object. It allows for various customizations such as grouping by metadata,
350+ # ' @description This function creates a cell velocity plot for a Seurat object,
351+ # ' a Giotto object, a path to an .h5ad file or an opened `H5File` by `hdf5r` package.
352+ # ' It allows for various customizations such as grouping by metadata,
278353# ' adding edges between cell neighbors, highlighting specific cells, and more.
279354# ' This function is a wrapper around [plotthis::VelocityPlot()], which provides a
280355# ' flexible way to visualize cell velocities in reduced dimensions. This function
281356# ' extracts the cell embeddings and velocity embeddings from the Seurat or Giotto object
282357# ' and passes them to [plotthis::VelocityPlot()].
283- # ' @param object A seurat object or a giotto object.
358+ # ' @param object A seurat object, a giotto object, a path to an .h5ad file or an opened `H5File` by `hdf5r` package .
284359# ' @param reduction Name of the reduction to plot (for example, "umap").
285360# ' @param v_reduction Name of the velocity reduction to plot (for example, "stochastic_umap").
286361# ' It should be the same as the reduction used to calculate the velocity.
@@ -293,6 +368,10 @@ CellDimPlot.Seurat <- function(
293368# ' @seealso [CellDimPlot()]
294369# ' @importFrom SeuratObject DefaultDimReduc Embeddings Reductions
295370# ' @importFrom plotthis VelocityPlot
371+ # ' @details See:
372+ # ' * <https://pwwang.github.io/scplotter/articles/Working_with_anndata_h5ad_files.html>
373+ # '
374+ # ' for examples of using this function with .h5ad files.
296375# ' @examples
297376# ' \donttest{
298377# ' data(pancreas_sub)
@@ -402,3 +481,70 @@ CellVelocityPlot.Seurat <- function(
402481 ...
403482 )
404483}
484+
485+
486+ # ' @export
487+ CellVelocityPlot.character <- function (
488+ object , reduction , v_reduction , spat_unit = NULL , feat_type = NULL , group_by = NULL , ...
489+ ) {
490+ if (! endsWith(object , " .h5ad" )) {
491+ stop(" [CellVelocityPlot] Currently only supports .h5ad files when called with a string/path." )
492+ }
493+
494+ object <- hdf5r :: H5File $ new(object , mode = " r" )
495+ on.exit(object $ close_all())
496+
497+ CellVelocityPlot.H5File(
498+ object = object , reduction = reduction , v_reduction = v_reduction ,
499+ spat_unit = spat_unit , feat_type = feat_type , group_by = group_by , ...
500+ )
501+ }
502+
503+ # ' @export
504+ CellVelocityPlot.H5File <- function (
505+ object , reduction , v_reduction , spat_unit = NULL , feat_type = NULL , group_by = NULL , ...
506+ ) {
507+ stopifnot(" [CellVelocityPlot] 'spat_unit' and 'feat_type' are not used for anndata." =
508+ is.null(spat_unit ) && is.null(feat_type ))
509+
510+ reduc_info <- names(object [[' obsm' ]])
511+ if (is.null(reduc_info ) || length(reduc_info ) == 0 ) {
512+ stop(" [CellVelocityPlot] The object does not have any reductions." )
513+ }
514+
515+ if (! startsWith(reduction , " X_" ) && ! reduction %in% reduc_info ) {
516+ reduction <- paste0(" X_" , reduction )
517+ }
518+
519+ if (! reduction %in% reduc_info ) {
520+ stop(" [CellVelocityPlot] The object does not have reduction:" , reduction )
521+ }
522+ if (! v_reduction %in% reduc_info ) {
523+ stop(" [CellVelocityPlot] The object does not have velocity reduction:" , v_reduction )
524+ }
525+
526+ if (! is.null(group_by )) {
527+ metakeys <- names(object [[' obs' ]])
528+ if (! group_by %in% metakeys ) {
529+ stop(" [CellVelocityPlot] The object does not have metadata column:" , group_by )
530+ }
531+ if (inherits(object [[' obs' ]][[group_by ]], " H5Group" ) &&
532+ setequal(names(object [[' obs' ]][[group_by ]]), c(" categories" , " codes" ))) {
533+ codes <- object [[' obs' ]][[group_by ]][[' codes' ]]$ read()
534+ categories <- object [[' obs' ]][[group_by ]][[' categories' ]]$ read()
535+ group_by <- factor (categories [codes + 1 ], levels = categories )
536+ } else if (inherits(object [[' obs' ]][[group_by ]], " H5Group" )) {
537+ stop(" [CellVelocityPlot] Complex data structure detected in metadata (obs) column:" , group_by )
538+ } else {
539+ # Read the metadata column directly
540+ group_by <- object [[' obs' ]][[group_by ]]$ read()
541+ }
542+ }
543+
544+ VelocityPlot(
545+ embedding = t(object [[" obsm" ]][[reduction ]]$ read())[, 1 : 2 , drop = FALSE ],
546+ v_embedding = t(object [[" obsm" ]][[v_reduction ]]$ read())[, 1 : 2 , drop = FALSE ],
547+ group_by = group_by ,
548+ ...
549+ )
550+ }
0 commit comments