CARD icon indicating copy to clipboard operation
CARD copied to clipboard

Rotate CARD plots?

Open hcjarnagin opened this issue 11 months ago • 2 comments

Hi there! Thanks for making and documenting such a nice package!

Is there anyway you can rotate the spatial plots?

Using the function copied below, I've been able to rotate the seurat-based images and projections. Is there a similar way to do this with CARD's plots?

`# flip_angle %in% c(180, "R90", "L90", "Hf", "Vf")

rotimat=function(foo,rotation){ if(!is.matrix(foo)){ cat("Input is not a matrix") return(foo) } if(!(rotation %in% c("180","Hf","Vf", "R90", "L90"))){ cat("Rotation should be either L90, R90, 180, Hf or Vf\n") return(foo) } if(rotation == "180"){ foo <- foo %>% .[, dim(.)[2]:1] %>% .[dim(.)[1]:1, ] } if(rotation == "Hf"){ foo <- foo %>% .[, dim(.)[2]:1] }

if(rotation == "Vf"){
    foo <- foo %>%
        .[dim(.)[1]:1, ]
}
if(rotation == "L90"){
    foo = t(foo)
    foo <- foo %>%
        .[dim(.)[1]:1, ]
}
if(rotation == "R90"){
    foo = t(foo)
    foo <- foo %>%
        .[, dim(.)[2]:1]
}
return(foo)

}

rotateSeuratImage = function(seuratVisumObject, slide = "slice1", rotation="Vf"){ if(!(rotation %in% c("180","Hf","Vf", "L90", "R90"))){ cat("Rotation should be either 180, L90, R90, Hf or Vf\n") return(NULL) }else{ seurat.visium = seuratVisumObject ori.array = (seurat.visium@images)[[slide]]@image img.dim = dim(ori.array)[1:2]/(seurat.visium@images)[[slide]]@scale.factors$lowres new.mx <- c()
# transform the image array for (rgb_idx in 1:3){ each.mx <- ori.array[,,rgb_idx] each.mx.trans <- rotimat(each.mx, rotation) new.mx <- c(new.mx, list(each.mx.trans)) }

    # construct new rgb image array
    new.X.dim <- dim(each.mx.trans)[1]
    new.Y.dim <- dim(each.mx.trans)[2]
    new.array <- array(c(new.mx[[1]],
                         new.mx[[2]],
                         new.mx[[3]]), 
                       dim = c(new.X.dim, new.Y.dim, 3))
    
    #swap old image with new image
    seurat.visium@images[[slide]]@image <- new.array
    
    ## step4: change the tissue pixel-spot index
    img.index <- (seurat.visium@images)[[slide]]@coordinates
    
    #swap index
    if(rotation == "Hf"){
        seurat.visium@images[[slide]]@coordinates$imagecol <- img.dim[2]-img.index$imagecol
    }
    
    if(rotation == "Vf"){
        seurat.visium@images[[slide]]@coordinates$imagerow <- img.dim[1]-img.index$imagerow
    }
    
    if(rotation == "180"){
        seurat.visium@images[[slide]]@coordinates$imagerow <- img.dim[1]-img.index$imagerow
        seurat.visium@images[[slide]]@coordinates$imagecol <- img.dim[2]-img.index$imagecol
    }
    
    if(rotation == "L90"){
        seurat.visium@images[[slide]]@coordinates$imagerow <- img.dim[2]-img.index$imagecol
        seurat.visium@images[[slide]]@coordinates$imagecol <- img.index$imagerow
    }
    
    if(rotation == "R90"){
        seurat.visium@images[[slide]]@coordinates$imagerow <- img.index$imagecol
        seurat.visium@images[[slide]]@coordinates$imagecol <- img.dim[1]-img.index$imagerow
    }
    
    return(seurat.visium)
}  

}`

hcjarnagin avatar Mar 25 '24 14:03 hcjarnagin

Hi @hcjarnagin,

Thank you for your interest in our package.

Currently the visualizations in CARD just plot the original coordinates. But you should be able to modify the CARD_obj@spatial_location by rotating the coordinates, following Seurat's functions.

For example, assuming you want to rotate the coordinates by 90 degrees clockwise.

loc <- CARD_obj@spatial_location
loc$new_x <- loc$y
loc$new_y <- -loc$x
CARD_obj@spatial_location <- loc[,c("new_x","new_y")]

Now you can proceed with the usual plotting function in CARD using the updated spatial_location.

Hope this helps!

Best, Ying

YMalab avatar Apr 01 '24 16:04 YMalab

Thanks, it worked perfectly for me. Also, when plotting with CARD.visualize.pie, I had to change the coord_fixed after I changed the coordinates in order to keep the plot ratio:

p1 <- CARD.visualize.pie(
	proportion = CARD_obj@Proportion_CARD,
	spatial_location = loc, 
 	colors = colors, 
  	radius = 0.52)   +
              coord_fixed(ratio = 1 * max(loc$x)/max(loc$y))  # initial setting

new setting: invert loc$x and loc$y if loc$new_x <- loc$y and loc$new_y <- loc$x put min(loc$x) instead of max(loc$x) if loc$ x <- -loc$x

abasseville avatar Apr 25 '24 14:04 abasseville

Thank you so much for your comments and help with this! An error was thrown if I tried to add the coord_fixed() to the CARD plot after manipulating it once. Below is the code I got working to rotate and fix the image's ratio with no errors.

loc <- CARDobject@spatial_location

ggplot(loc, aes(x = x, y = y)) +
  geom_point()

# Rotate the coordinates by 90 degrees
rotated_loc <- data.frame(
  x = -loc$y,  # Negating y and swapping x and y
  y = loc$x
)

ratio <- 1 * min(rotated_loc$x) / max(rotated_loc$y)

# Apply the ratio to adjust the coordinates
rotated_loc$x_adj <- rotated_loc$x
rotated_loc$y_adj <- rotated_loc$y * ratio

rotated_loc$x <-NULL
rotated_loc$y <- NULL
names(rotated_loc)<-c("x", "y")
rownames(rotated_loc)<-rownames(loc)
# Plot the adjusted coordinates
ggplot(rotated_loc, aes(x = x, y = y)) +
  geom_point()


CARD.visualize.pie(
    proportion =test@Proportion_CARD,
    spatial_location = loc,
    colors = colors,
    radius = 3.0) + theme(legend.position = "right") + ggtitle(paste("Original"))

CARD.visualize.pie(
	proportion = test@Proportion_CARD,
	spatial_location = rotated_loc, 
 	colors = colors, 
  	radius = 3)  + theme(legend.position = "right") + ggtitle(paste("Rotated"))

hcjarnagin avatar May 13 '24 19:05 hcjarnagin