Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: rework image plotting #59

Merged
merged 2 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: GiottoVisuals
Title: Visuals for the Giotto spatial biology analysis ecosystem
Version: 0.1.3
Version: 0.1.4
Authors@R: c(
person("Ruben", "Dries", email = "[email protected]",
role = c("aut", "cre")),
Expand Down Expand Up @@ -82,6 +82,8 @@ Collate:
'colorRamp2.R'
'color_palettes.R'
'dd.R'
'generics.R'
'gg_annotation_raster.R'
'gg_info_layers.R'
'globals.R'
'gstop.R'
Expand Down
6 changes: 5 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@

# GiottoVisuals 0.1.3 (2024/01/25)
# GiottoVisuals 0.1.4 (2024/01/25)
## bug fixes
- fix plotting color gradient when using param `point_shape = "no_border"`
- fix image NA value [#865](https://github.com/drieslab/Giotto/issues/865) by rbutleriii

## new
- `gg_annotation_raster()` internal generic for adding a `giottoImage`, `giottoLargeImage`, or `list` thereof to a `ggplot` object

# GiottoVisuals 0.1.2 (2023/01/12)

Expand Down
4 changes: 4 additions & 0 deletions R/generics.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

# internals
setOldClass("gg")
setGeneric("gg_annotation_raster", function(ggobj, gimage, ...) standardGeneric("gg_annotation_raster"))

Check notice

Code scanning / lintr

Lines should not be more than 80 characters. This line is 104 characters. Note

Lines should not be more than 80 characters. This line is 104 characters.
113 changes: 113 additions & 0 deletions R/gg_annotation_raster.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@

#' @name gg_annotation_raster
#' @keywords internal
#' @title Append image to ggplot as annotation_raster
#' @param ggobj ggplot2 `gg` object
#' @param gimage `giottoLargeImage`, `giottoImage` or `list` thereof
#' @return `gg` object with images to plot appended as annotation rasters
NULL

#' @rdname gg_annotation_raster
setMethod(
"gg_annotation_raster",
signature(ggobj = "gg", gimage = "list"),
function(ggobj, gimage, ...)
{

Check notice

Code scanning / lintr

Opening curly braces should never go on their own line and should always be followed by a new line. Note

Opening curly braces should never go on their own line and should always be followed by a new line.
for(i in seq_along(gimage)) {

Check notice

Code scanning / lintr

Place a space before left parenthesis, except in a function call. Note

Place a space before left parenthesis, except in a function call.
ggobj <- gg_annotation_raster(ggobj, gimage[[i]], ...)
}
return(ggobj)
}
)

#' @rdname gg_annotation_raster
setMethod(
"gg_annotation_raster",
signature(ggobj = "gg", gimage = "giottoImage"),
function(ggobj, gimage, ...)
{

Check notice

Code scanning / lintr

Opening curly braces should never go on their own line and should always be followed by a new line. Note

Opening curly braces should never go on their own line and should always be followed by a new line.
# extract min and max from object
my_xmax = gimage@minmax[1]

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.
my_xmin = gimage@minmax[2]

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.
my_ymax = gimage@minmax[3]

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.
my_ymin = gimage@minmax[4]

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.

# convert giotto image object into array
img_array = as.numeric(gimage@mg_object[[1]])

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.

# extract adjustments from object
xmax_b = gimage@boundaries[1]

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.
xmin_b = gimage@boundaries[2]

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.
ymax_b = gimage@boundaries[3]

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.
ymin_b = gimage@boundaries[4]

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.

# append to ggobj
ggobj <- ggobj + annotation_raster(
img_array,
xmin = my_xmin-xmin_b, xmax = my_xmax+xmax_b,

Check notice

Code scanning / lintr

Put spaces around all infix operators. Note

Put spaces around all infix operators.

Check notice

Code scanning / lintr

Put spaces around all infix operators. Note

Put spaces around all infix operators.
ymin = my_ymin-ymin_b, ymax = my_ymax+ymax_b

Check notice

Code scanning / lintr

Put spaces around all infix operators. Note

Put spaces around all infix operators.

Check notice

Code scanning / lintr

Put spaces around all infix operators. Note

Put spaces around all infix operators.
)

# TODO geom_raster to accommodate single-channel
return(ggobj)
}
)

#' @rdname gg_annotation_raster
setMethod(
"gg_annotation_raster",
signature(ggobj = "gg", gimage = "giottoLargeImage"),
function(ggobj, gimage, ...)
{

Check notice

Code scanning / lintr

Opening curly braces should never go on their own line and should always be followed by a new line. Note

Opening curly braces should never go on their own line and should always be followed by a new line.
# get plotting minmax
extent = terra::ext(gimage@raster_object)[1:4]

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.
xmin = extent[['xmin']]

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.

Check notice

Code scanning / lintr

Only use double-quotes. Note

Only use double-quotes.
xmax = extent[['xmax']]

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.

Check notice

Code scanning / lintr

Only use double-quotes. Note

Only use double-quotes.
ymin = extent[['ymin']]

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.

Check notice

Code scanning / lintr

Only use double-quotes. Note

Only use double-quotes.
ymax = extent[['ymax']]

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.

Check notice

Code scanning / lintr

Only use double-quotes. Note

Only use double-quotes.

# convert raster object into array with 3 channels
img_array = terra::as.array(gimage@raster_object)

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.

# TODO: check if required, fixes NaN values
# replacing NA's by zero or another value directly in raster object?
# raster[is.na(raster[])] <- 0

Check notice

Code scanning / lintr

Commented code should be removed. Note

Commented code should be removed.
if (is.nan(max(img_array[,,1]))) {

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.
img_array[,,1][is.nan(img_array[,,1])] = max(img_array[,,1], na.rm = TRUE)

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.
}

if(dim(img_array)[3] > 1) {

Check notice

Code scanning / lintr

Place a space before left parenthesis, except in a function call. Note

Place a space before left parenthesis, except in a function call.
if(is.nan(max(img_array[,,2]))) {

Check notice

Code scanning / lintr

Place a space before left parenthesis, except in a function call. Note

Place a space before left parenthesis, except in a function call.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.
img_array[,,2][is.nan(img_array[,,2])] = max(img_array[,,2], na.rm = TRUE)

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Lines should not be more than 80 characters. This line is 82 characters. Note

Lines should not be more than 80 characters. This line is 82 characters.
}
}

if(dim(img_array)[3] > 2) {

Check notice

Code scanning / lintr

Place a space before left parenthesis, except in a function call. Note

Place a space before left parenthesis, except in a function call.
if(is.nan(max(img_array[,,3]))) {

Check notice

Code scanning / lintr

Place a space before left parenthesis, except in a function call. Note

Place a space before left parenthesis, except in a function call.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.
img_array[,,3][is.nan(img_array[,,3])] = max(img_array[,,3], na.rm = TRUE)

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Lines should not be more than 80 characters. This line is 82 characters. Note

Lines should not be more than 80 characters. This line is 82 characters.
}
}

img_array = img_array/max(img_array, na.rm = TRUE)

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.

Check notice

Code scanning / lintr

Put spaces around all infix operators. Note

Put spaces around all infix operators.
if(dim(img_array)[3] == 1) {

Check notice

Code scanning / lintr

Place a space before left parenthesis, except in a function call. Note

Place a space before left parenthesis, except in a function call.
img_array_RGB = array(NA, dim = c(dim(img_array)[1:2],3))

Check notice

Code scanning / lintr

Variable and function name style should match snake_case or symbols. Note

Variable and function name style should match snake_case or symbols.

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.
img_array_RGB[,,1:3] = img_array

Check notice

Code scanning / lintr

Variable and function name style should match snake_case or symbols. Note

Variable and function name style should match snake_case or symbols.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Commas should always have a space after. Note

Commas should always have a space after.

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.
} else {
img_array_RGB = img_array

Check notice

Code scanning / lintr

Variable and function name style should match snake_case or symbols. Note

Variable and function name style should match snake_case or symbols.

Check notice

Code scanning / lintr

Use <-, not =, for assignment. Note

Use <-, not =, for assignment.
}

# handle NA values
img_array_RGB[is.na(img_array_RGB)] <- 0

Check notice

Code scanning / lintr

Variable and function name style should match snake_case or symbols. Note

Variable and function name style should match snake_case or symbols.

# append to ggobj
ggobj <- ggobj + annotation_raster(
img_array_RGB,
xmin = xmin, xmax = xmax,
ymin = ymin, ymax = ymax
)

# TODO geom_raster to accommodate single-channel
return(ggobj)
}
)

Check notice

Code scanning / lintr

Trailing blank lines are superfluous. Note

Trailing blank lines are superfluous.
146 changes: 2 additions & 144 deletions R/gg_info_layers.R
Original file line number Diff line number Diff line change
Expand Up @@ -1350,151 +1350,9 @@ plot_spat_image_layer_ggplot = function(gg_obj,
# Assign region to plot
gg_obj = gg_obj + geom_blank(data = spat_ext, aes_string(sdimx, sdimy))

if((inherits(gimage, 'list') | is.vector(gimage)) & length(gimage) > 1) {

for(i in 1:length(gimage)) {

if(inherits(gimage[[i]], 'giottoImage')) {
# extract min and max from object
my_xmax = gimage[[i]]@minmax[1]
my_xmin = gimage[[i]]@minmax[2]
my_ymax = gimage[[i]]@minmax[3]
my_ymin = gimage[[i]]@minmax[4]

# convert giotto image object into array
img_array = as.numeric(gimage[[i]]@mg_object[[1]])

# extract adjustments from object
xmax_b = gimage[[i]]@boundaries[1]
xmin_b = gimage[[i]]@boundaries[2]
ymax_b = gimage[[i]]@boundaries[3]
ymin_b = gimage[[i]]@boundaries[4]

gg_obj = gg_obj + annotation_raster(img_array,
xmin = my_xmin-xmin_b, xmax = my_xmax+xmax_b,
ymin = my_ymin-ymin_b, ymax = my_ymax+ymax_b)

# TODO geom_raster to accommodate single-channel

} else if(inherits(gimage[[i]], 'giottoLargeImage')) {
# get plotting minmax
extent = terra::ext(gimage[[i]]@raster_object)[1:4]
xmin = extent[['xmin']]
xmax = extent[['xmax']]
ymin = extent[['ymin']]
ymax = extent[['ymax']]

# convert raster object into array with 3 channels
img_array = terra::as.array(gimage[[i]]@raster_object)

# TODO: check if required, fixes NaN values
# replacing NA's by zero or another value directly in raster object?
# raster[is.na(raster[])] <- 0
if(is.nan(max(img_array[,,1]))) {
img_array[,,1][is.nan(img_array[,,1])] = max(img_array[,,1], na.rm = T)
}

if(dim(img_array)[3] > 1) {
if(is.nan(max(img_array[,,2]))) {
img_array[,,2][is.nan(img_array[,,2])] = max(img_array[,,2], na.rm = T)
}
}

if(dim(img_array)[3] > 2) {
if(is.nan(max(img_array[,,3]))) {
img_array[,,3][is.nan(img_array[,,3])] = max(img_array[,,3], na.rm = T)
}
}



# Assign image(s) to plot
gg_obj <- gg_annotation_raster(ggobj = gg_obj, gimage = gimage)

img_array = img_array/max(img_array, na.rm = TRUE)
if(dim(img_array)[3] == 1) {
img_array_RGB = array(NA, dim = c(dim(img_array)[1:2],3))
img_array_RGB[,,1:3] = img_array
img_array_RGB[is.na(img_array_RGB)] = 0
} else {
img_array_RGB = img_array
}

gg_obj = gg_obj + annotation_raster(img_array_RGB,
xmin = xmin, xmax = xmax,
ymin = ymin, ymax = ymax)

# TODO geom_raster to accommodate single-channel
}

}

} else {

if(methods::is(gimage, 'giottoImage')) {
# extract min and max from object
my_xmax = gimage@minmax[1]
my_xmin = gimage@minmax[2]
my_ymax = gimage@minmax[3]
my_ymin = gimage@minmax[4]

# convert giotto image object into array
img_array = as.numeric(gimage@mg_object[[1]])

# extract adjustments from object
xmax_b = gimage@boundaries[1]
xmin_b = gimage@boundaries[2]
ymax_b = gimage@boundaries[3]
ymin_b = gimage@boundaries[4]

gg_obj = gg_obj + annotation_raster(img_array,
xmin = my_xmin-xmin_b, xmax = my_xmax+xmax_b,
ymin = my_ymin-ymin_b, ymax = my_ymax+ymax_b)

} else if(methods::is(gimage, 'giottoLargeImage')) {
# get plotting minmax
extent = terra::ext(gimage@raster_object)[1:4]
xmin = extent[['xmin']]
xmax = extent[['xmax']]
ymin = extent[['ymin']]
ymax = extent[['ymax']]

# convert raster object into array with 3 channels
img_array = terra::as.array(gimage@raster_object)

# TODO: check if required, fixes NaN values
# replacing NA's by zero or another value directy in raster object?
# raster[is.na(raster[])] <- 0
if(is.nan(max(img_array[,,1]))) {
img_array[,,1][is.nan(img_array[,,1])] = max(img_array[,,1], na.rm = T)
}

if(dim(img_array)[3] > 1) {
if(is.nan(max(img_array[,,2]))) {
img_array[,,2][is.nan(img_array[,,2])] = max(img_array[,,2], na.rm = T)
}
}

if(dim(img_array)[3] > 2) {
if(is.nan(max(img_array[,,3]))) {
img_array[,,3][is.nan(img_array[,,3])] = max(img_array[,,3], na.rm = T)
}
}

img_array = img_array/max(img_array, na.rm = TRUE)
if(dim(img_array)[3] == 1) {
img_array_RGB = array(NA, dim = c(dim(img_array)[1:2],3))
img_array_RGB[,,1:3] = img_array
img_array_RGB[is.na(img_array_RGB)] = 0
} else {
img_array_RGB = img_array
}

gg_obj <- gg_obj +
annotation_raster(img_array_RGB,
xmin = xmin, xmax = xmax,
ymin = ymin, ymax = ymax)
}

}

if(!is.null(spatlocs)) {
gg_obj <- gg_obj +
Expand Down
Loading
Loading