1- # ' Convert a data.frame to a terra SpatVector polygon
2- # ' @keywords internal
3- .df_to_polygon_spatvector <- function (
4- df , id , x , y ,
5- attrs = NULL
6- ) {
7- shapes <- split(df [, c(x , y ), drop = FALSE ], df [[id ]])
8- sv <- terra :: vect(lapply(shapes , as.matrix ), type = " polygons" )
9- if (! is.null(attrs )) {
10- for (attr in attrs ) {
11- # only get the first value of each polygon
12- sv [[attr ]] <- sapply(split(df [[attr ]], df [[id ]]), function (x ) x [1 ])
13- }
14- }
15- sv
16- }
17-
181# ' Process points layer for Seurat spatial plots
192# ' @keywords internal
203.seurat_points_layer <- function (
10386 points_args $ legend.direction <- legend.direction
10487 points_args $ flip_y <- points_args $ flip_y
10588 points_args $ return_layer <- TRUE
106- player <- do.call(SpatialPointsPlot , points_args )
89+ player <- do.call(SpatPointsPlot , points_args )
10790
10891 list (player = player , facet_by = facet_by )
10992}
133116# ' @param ... Additional arguments passed to the plotting functions.
134117# ' @return A ggplot object
135118# ' @keywords internal
136- # ' @rdname SpatialPlot
119+ # ' @rdname SpatPlot
137120SpatPlot <- function (object , ... ) {
138121 UseMethod(" SpatPlot" , object )
139122}
140123
141124# ' @keywords internal
142- # ' @rdname SpatialPlot
125+ # ' @rdname SpatPlot
143126SpatPlot.Seurat <- function (object , image = NULL , ... ) {
144127 first_image <- Seurat :: Images(object )[1 ]
145128 if (is.null(first_image )) {
@@ -161,8 +144,8 @@ SpatPlot.Seurat <- function(object, image = NULL, ...) {
161144}
162145
163146# ' @keywords internal
164- # ' @rdname SpatialPlot
165- # ' @importFrom plotthis SpatialImagePlot SpatialMasksPlot SpatialShapesPlot SpatialPointsPlot
147+ # ' @rdname SpatPlot
148+ # ' @importFrom plotthis SpatImagePlot SpatMasksPlot SpatShapesPlot SpatPointsPlot
166149SpatPlot.Seurat.Visium <- function (
167150 object , image = NULL , masks = NULL , shapes = NULL , points = NULL , ext = NULL , points_x = " x" , points_y = " y" ,
168151 image_scale = NULL , crop = TRUE , group_by = NULL , features = NULL , layer = " data" , scale_factor = NULL ,
@@ -235,7 +218,7 @@ SpatPlot.Seurat.Visium <- function(
235218 image_args $ flip_y <- flip_y
236219 image_args $ return_layer <- TRUE
237220 image_args $ ext <- if (! is.null(ext_unscaled )) ext_unscaled * the_scale_factor
238- player <- do.call(SpatialImagePlot , image_args )
221+ player <- do.call(SpatImagePlot , image_args )
239222 scales_reused <- intersect(scales_used , attr(player , " scales" ))
240223 players <- c(players , list (player ))
241224 scales_used <- unique(c(scales_used , attr(player , " scales" )))
@@ -302,7 +285,7 @@ SpatPlot.Seurat.Visium <- function(
302285}
303286
304287# ' @keywords internal
305- # ' @rdname SpatialPlot
288+ # ' @rdname SpatPlot
306289SpatPlot.Seurat.SlideSeq <- function (
307290 object , image = NULL , masks = NULL , shapes = NULL , points = NULL , ext = NULL ,
308291 image_scale = NULL , crop = TRUE , group_by = NULL , features = NULL , layer = " data" ,
@@ -425,8 +408,8 @@ SpatPlot.Seurat.SlideSeq <- function(
425408}
426409
427410# ' @keywords internal
428- # ' @rdname SpatialPlot
429- # ' @importFrom plotthis SpatialImagePlot SpatialMasksPlot SpatialShapesPlot SpatialPointsPlot
411+ # ' @rdname SpatPlot
412+ # ' @importFrom plotthis SpatImagePlot SpatMasksPlot SpatShapesPlot SpatPointsPlot
430413SpatPlot.Seurat.FOV <- function (
431414 object , image = NULL , masks = NULL , shapes = NULL , points = NULL , ext = NULL , points_x = " x" , points_y = " y" ,
432415 image_scale = NULL , crop = TRUE , group_by = NULL , features = NULL , layer = " data" , scale_factor = NULL ,
@@ -499,7 +482,7 @@ SpatPlot.Seurat.FOV <- function(
499482 image_args $ flip_y <- flip_y
500483 image_args $ return_layer <- TRUE
501484 image_args $ ext <- if (! is.null(ext_unscaled )) ext_unscaled * the_scale_factor
502- player <- do.call(SpatialImagePlot , image_args )
485+ player <- do.call(SpatImagePlot , image_args )
503486 scales_reused <- intersect(scales_used , attr(player , " scales" ))
504487 players <- c(players , list (player ))
505488 scales_used <- unique(c(scales_used , attr(player , " scales" )))
@@ -566,18 +549,19 @@ SpatPlot.Seurat.FOV <- function(
566549}
567550
568551# ' @keywords internal
569- # ' @rdname SpatialPlot
552+ # ' @rdname SpatPlot
570553SpatPlot.giotto <- function (
571554 object ,
572555 image = NULL ,
573556 masks = NULL ,
574557 shapes = NULL ,
575558 points = NULL ,
559+ graph = NULL ,
576560 ext = NULL ,
577561 layer = c(" normalized" , " scaled" , " custom" , " raw" ),
578562 layers = NULL ,
579563 flip_y = FALSE ,
580- group_by = " shapes " ,
564+ group_by = NULL ,
581565 feat_type = " rna" ,
582566 features = NULL ,
583567 nmols = 1000 ,
@@ -625,6 +609,9 @@ SpatPlot.giotto <- function(
625609 if (isTRUE(image )) {
626610 image <- names(object @ images )[1 ]
627611 }
612+ if (is.null(points ) && ! is.null(graph )) {
613+ points <- TRUE
614+ }
628615 points <- points %|| % TRUE
629616 shapes <- shapes %|| % (if (identical(group_by , " shapes" ) || ! is.null(shapes_fill_by )) TRUE )
630617 layers <- intersect(
@@ -645,20 +632,37 @@ SpatPlot.giotto <- function(
645632 shapes_alpha <- shapes_alpha %|| % ifelse(" image" %in% layers , 0.5 , 1 )
646633 for (element in layers ) {
647634 if (element == " image" ) {
648- image_obj <- GiottoClass :: getGiottoImage(gobject = object , name = image )
649- ext <- ext %|| % as.vector(terra :: ext(image_obj ))
650- image_args <- args [startsWith(names(args ), " image_" )]
651- names(image_args ) <- sub(" ^image_" , " " , names(image_args ))
652- image_args $ data <- image_obj @ raster_object
653- image_args $ flip_y <- flip_y
654- image_args $ return_layer <- TRUE
655- image_args $ ext <- ext
656- image_colors <- attr(image_obj , " colors" )
657- if (! is.null(image_colors )) { image_args $ palcolor <- image_colors }
658- player <- do.call(SpatialImagePlot , image_args )
659- scales_reused <- intersect(scales_used , attr(player , " scales" ))
660- players <- c(players , .new_scale_layers(scales_reused ), list (player ))
661- scales_used <- unique(c(scales_used , attr(player , " scales" )))
635+ if (image %in% names(object @ images )) {
636+ image_obj <- GiottoClass :: getGiottoImage(gobject = object , name = image )
637+ ext <- ext %|| % as.vector(terra :: ext(image_obj ))
638+ image_args <- args [startsWith(names(args ), " image_" )]
639+ names(image_args ) <- sub(" ^image_" , " " , names(image_args ))
640+ image_args $ data <- image_obj @ raster_object
641+ image_args $ flip_y <- flip_y
642+ image_args $ return_layer <- TRUE
643+ image_args $ ext <- ext
644+ image_colors <- attr(image_obj , " colors" )
645+ if (! is.null(image_colors )) { image_args $ palcolor <- image_colors }
646+ player <- do.call(SpatImagePlot , image_args )
647+ scales_reused <- intersect(scales_used , attr(player , " scales" ))
648+ players <- c(players , .new_scale_layers(scales_reused ), list (player ))
649+ scales_used <- unique(c(scales_used , attr(player , " scales" )))
650+ } else {
651+ # use as a color to plot a background rect
652+ image_args <- args [startsWith(names(args ), " image_" )]
653+ names(image_args ) <- sub(" ^image_" , " " , names(image_args ))
654+ image_args $ data = data.frame (x = 0 , y = 0 ) # dummy data
655+ image_args $ xmin = - Inf
656+ image_args $ xmax = Inf
657+ image_args $ ymin = - Inf
658+ image_args $ ymax = Inf
659+ image_args $ fill <- image
660+ image_args $ color <- NA
661+ player <- do.call(ggplot2 :: geom_rect , image_args )
662+ scales_reused <- intersect(scales_used , " fill" )
663+ players <- c(players , .new_scale_layers(scales_reused ), list (player ))
664+ scales_used <- unique(c(scales_used , attr(player , " scales" )))
665+ }
662666 } else if (element == " masks" ) {
663667 stop(" [SpatPlot] 'masks' is not supported for Giotto objects yet." )
664668 } else if (element == " shapes" ) {
@@ -693,32 +697,39 @@ SpatPlot.giotto <- function(
693697 shapes_args <- args [startsWith(names(args ), " shapes_" )]
694698 names(shapes_args ) <- sub(" ^shapes_" , " " , names(shapes_args ))
695699
700+ shapes_args $ x <- " x"
701+ shapes_args $ y <- " y"
702+ shapes_args $ group <- " cell_ID"
703+
696704 if (! is.null(shapes_fill_by )) {
697- shapes_dt <- merge(
698- shapes_dt ,
699- suppressMessages(GiottoClass :: spatValues(
700- object ,
701- feats = shapes_fill_by ,
702- spat_unit = shapes_feat_type ,
703- feat_type = feat_type ,
704- spat_enr_name = spat_enr_names
705- )),
706- by = " cell_ID" ,
707- all.x = TRUE ,
708- suffixes = c(" .x" , " " )
709- )
710- shapes_args $ data <- .df_to_polygon_spatvector(shapes_dt , " cell_ID" , " x" , " y" , attrs = shapes_fill_by )
705+ # It should be a color name
706+ if (length(shapes_fill_by ) > 1 || shapes_fill_by %in% GiottoClass :: featIDs(object , feat_type = shapes_feat_type )) {
707+ shapes_dt <- merge(
708+ shapes_dt ,
709+ suppressMessages(GiottoClass :: spatValues(
710+ object ,
711+ feats = shapes_fill_by ,
712+ spat_unit = shapes_feat_type ,
713+ feat_type = feat_type ,
714+ spat_enr_name = spat_enr_names
715+ )),
716+ by = " cell_ID" ,
717+ all.x = TRUE ,
718+ suffixes = c(" .x" , " " )
719+ )
720+ }
721+ shapes_args $ data <- shapes_dt
711722 shapes_args $ fill_by <- shapes_fill_by
712723 shapes_args $ legend.position <- shapes_args $ legend.position %|| % " right"
713724 shapes_args $ legend.direction <- shapes_args $ legend.direction %|| % " vertical"
714725 } else {
715- shapes_args $ data <- .df_to_polygon_spatvector( shapes_dt , " cell_ID " , " x " , " y " )
726+ shapes_args $ data <- shapes_dt
716727 }
717728 shapes_args $ flip_y <- flip_y
718729 shapes_args $ return_layer <- TRUE
719730 shapes_args $ alpha <- shapes_alpha
720- shapes_args $ ext <- ext %|| % as.vector( terra :: ext( shapes_args $ data ))
721- player <- do.call(SpatialShapesPlot , shapes_args )
731+ shapes_args $ ext <- ext %|| % c(range( shapes_dt $ x , na.rm = TRUE ), range( shapes_dt $ y , na.rm = TRUE ))
732+ player <- do.call(SpatShapesPlot , shapes_args )
722733 scales_reused <- intersect(scales_used , attr(player , " scales" ))
723734 players <- c(players , .new_scale_layers(scales_reused ), list (player ))
724735 scales_used <- unique(c(scales_used , attr(player , " scales" )))
@@ -759,6 +770,13 @@ SpatPlot.giotto <- function(
759770 points_args $ data <- data.table :: rbindlist(points_args $ data , fill = TRUE )
760771 } else if (! is.null(group_by )) {
761772 # prepare the cell metadata
773+ points_args $ data <- GiottoClass :: combineCellData(
774+ gobject = object ,
775+ feat_type = feat_type ,
776+ spat_loc_name = spat_loc_name ,
777+ spat_enr_name = spat_enr_names ,
778+ include_spat_locs = FALSE
779+ )[[feat_type ]]
762780 } else { # expression or just locations
763781 points_args $ data <- GiottoClass :: getSpatialLocations(
764782 gobject = object ,
@@ -768,6 +786,21 @@ SpatPlot.giotto <- function(
768786 )
769787 }
770788
789+ if (! is.null(graph )) {
790+ points_args $ graph <- GiottoClass :: getSpatialNetwork(
791+ gobject = object ,
792+ spat_unit = spat_unit ,
793+ name = if (! isTRUE(graph )) graph ,
794+ output = " networkDT" ,
795+ verbose = FALSE
796+ )
797+ points_args $ graph_x <- " sdimx_begin"
798+ points_args $ graph_y <- " sdimy_begin"
799+ points_args $ graph_xend <- " sdimx_end"
800+ points_args $ graph_yend <- " sdimy_end"
801+ points_args $ graph_value <- " weight"
802+ }
803+
771804 if (identical(group_by , " shapes" )) {
772805 points_args $ label <- FALSE
773806 } else if (identical(group_by , " molecules" )) {
@@ -812,11 +845,16 @@ SpatPlot.giotto <- function(
812845 }
813846 points_args $ legend.position <- points_args $ legend.position %|| % " right"
814847 points_args $ legend.direction <- points_args $ legend.direction %|| % " vertical"
848+ } else if (! is.null(group_by )) {
849+ points_args $ color_by <- group_by
850+ points_args $ color_name <- points_args $ color_name %|| % group_by
851+ points_args $ legend.position <- points_args $ legend.position %|| % " right"
852+ points_args $ legend.direction <- points_args $ legend.direction %|| % " vertical"
815853 }
816854 points_args $ flip_y <- flip_y
817855 points_args $ return_layer <- TRUE
818856 points_args $ ext <- ext
819- player <- do.call(SpatialPointsPlot , points_args )
857+ player <- do.call(SpatPointsPlot , points_args )
820858 scales_reused <- intersect(scales_used , attr(player , " scales" ))
821859 players <- c(players , .new_scale_layers(scales_reused ), list (player ))
822860 scales_used <- unique(c(scales_used , attr(player , " scales" )))
@@ -854,19 +892,19 @@ SpatPlot.giotto <- function(
854892# ' @param object A Seurat object or a Giotto object.
855893# ' @return A ggplot object
856894# ' @export
857- # ' @rdname SpatialPlot
895+ # ' @rdname SpatPlot
858896SpatFeaturePlot <- function (object , ... ) {
859897 UseMethod(" SpatFeaturePlot" , object )
860898}
861899
862900# ' @export
863- # ' @rdname SpatialPlot
901+ # ' @rdname SpatPlot
864902SpatFeaturePlot.Seurat <- function (object , image = NULL , ... ) {
865903 SpatPlot(object , image = image , ... )
866904}
867905
868906# ' @export
869- # ' @rdname SpatialPlot
907+ # ' @rdname SpatPlot
870908SpatFeaturePlot.giotto <- function (object , image = NULL , group_by = NULL , ... ) {
871909 stopifnot(
872910 " [SpatFeaturePlot] 'group_by' is not supported for Giotto objects. Use 'SpatDimPlot' instead." =
@@ -880,13 +918,13 @@ SpatFeaturePlot.giotto <- function(object, image = NULL, group_by = NULL, ...) {
880918# ' @param object A Seurat object or a Giotto object.
881919# ' @return A ggplot object
882920# ' @export
883- # ' @rdname SpatialPlot
921+ # ' @rdname SpatPlot
884922SpatDimPlot <- function (object , ... ) {
885923 UseMethod(" SpatDimPlot" , object )
886924}
887925
888926# ' @export
889- # ' @rdname SpatialPlot
927+ # ' @rdname SpatPlot
890928SpatDimPlot.Seurat <- function (object , image = NULL , group_by = NULL , ... ) {
891929 if (is.null(group_by )) {
892930 group_by <- " Identity"
@@ -896,8 +934,8 @@ SpatDimPlot.Seurat <- function(object, image = NULL, group_by = NULL, ...) {
896934}
897935
898936# ' @export
899- # ' @rdname SpatialPlot
937+ # ' @rdname SpatPlot
900938SpatDimPlot.giotto <- function (object , image = NULL , group_by = NULL , ... ) {
901- group_by <- group_by %|| % " shapes "
939+ group_by <- group_by %|| % " molecules "
902940 SpatPlot.giotto(object , image = image , group_by = group_by , ... )
903941}
0 commit comments