Skip to content

Commit

Permalink
add circos.raster
Browse files Browse the repository at this point in the history
  • Loading branch information
jokergoo committed Jun 13, 2017
1 parent 5f23f73 commit b48a900
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 9 deletions.
16 changes: 8 additions & 8 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@ Package: circlize
Type: Package
Title: Circular Visualization
Version: 0.4.0
Date: 2017-4-14
Date: 2017-5-29
Author: Zuguang Gu
Maintainer: Zuguang Gu <[email protected]>
Depends: R (>= 2.10.0), graphics
Depends: R (>= 3.0.0), graphics
Imports: GlobalOptions (>= 0.0.12), shape, grDevices, utils, stats,
colorspace, methods, grid
Suggests: knitr, dendextend (>= 1.0.1), ComplexHeatmap (>= 1.13.2), gridBase
VignetteBuilder: knitr
Description: Circular layout is an efficient way for the visualization of huge
amounts of information. Here the circlize package provides an implementation
amounts of information. Here this package provides an implementation
of circular layout generation in R as well as an enhancement of available
software. The flexibility of this package is based on the usage of low-level
software. The flexibility of the package is based on the usage of low-level
graphics functions such that self-defined high-level graphics can be easily
implemented by users for specific purposes. Together with the seamless
connection between the powerful computational and visual environment in R,
circlize gives users more convenience and freedom to design figures for
better understanding complex patterns behind multi-dimensional data.
it gives users more convenience and freedom to design figures for
better understanding complex patterns behind multiple dimensional data.
URL: https://github.com/jokergoo/circlize, http://jokergoo.github.io/circlize_book/book/
License: GPL (>= 2)
Packaged: 2017-4-14 00:00:00 UTC; Administrator
Packaged: 2017-5-29 00:00:00 UTC; Administrator
Repository: CRAN
Date/Publication: 2017-4-14 00:00:00
Date/Publication: 2017-5-29 00:00:00
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export(ux)
export(uy)

S3method(print, CELL_META)
S3method("$", CELL_META)
import(graphics)
importFrom("GlobalOptions", setGlobalOptions)
importFrom("colorspace", HLS)
Expand Down
2 changes: 1 addition & 1 deletion R/link.R
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ circos.link = function(sector.index1, point1, sector.index2, point2,
} else {
if(degreeDiff(theta1, theta21) > degreeDiff(theta1, theta22)) {
d1 = getQuadraticPoints(theta1, theta21, rou1, rou2, h = h, h.ratio = h.ratio, w = w)
d2 = getQuadraticPoints(theta1, theta22, rou1, rou2, h = h2, h.ratio = h.ratio, h.ratio = h.ratio, w = w2)
d2 = getQuadraticPoints(theta1, theta22, rou1, rou2, h = h2, h.ratio = h.ratio, w = w2)
d1x = getQuadraticPoints(theta1, theta21, rou1, rou2 - arr.length, h = h, h.ratio = h.ratio, w = w)
d2x = getQuadraticPoints(theta1, theta22, rou1, rou2 - arr.length, h = h2, h.ratio = h.ratio, w = w2)
dcenter = getQuadraticPoints(theta1, (theta21 + theta22)/2, rou1, rou2, h = (h+h2)/2, h.ratio = h.ratio, w = (w+w2)/2)
Expand Down
161 changes: 161 additions & 0 deletions R/raster.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@

# if facing %in% c("bending.inside", "bending.outside"), width and height
# can be numeric values
# else facing should be a string like "2cm"

image = system.file("img", "Rlogo.png", package = "png")

circos.initialize(letters[1:8], xlim = c(0, 1))
circos.track(ylim = c(0, 1), panel.fun = function(x, y) {
circos.raster(image, CELL_META$xcenter, CELL_META$ycenter, width = 1,
height = 1, facing = "bending.inside")
})
circos.track(ylim = c(0, 1), panel.fun = function(x, y) {
circos.raster(image, CELL_META$xcenter, CELL_META$ycenter, width = runif(1, 0.5, 1),
height = runif(1, 0.5, 1), facing = "bending.inside", niceFacing = TRUE)
})

circos.raster = function(image, x, y, width, height,
facing = c("inside", "outside", "reverse.clockwise", "clockwise",
"downward", "bending", "bending.inside", "bending.outside"),
niceFacing = FALSE, sector.index = get.cell.meta.data("sector.index"),
track.index = get.cell.meta.data("track.index"),
resolution = ifelse(grepl("bend", facing), 0.5, 1)) {

# convert image to Image class (in EBImage package)
if(inherits(image, "character")) {
image = readImage(image)
} else if(!inherits(image, "Image")) {
image = as.Image(image)
}
asp = dim(img)[1]/dim(img)[2]

facing = match.arg(facing)
if(facing %in% c("bending.inside", "bending.outside")) {

if(niceFacing) {
degree = circlize(x, y, sector.index = sector.index, track.index = track.index)[, 1]
degree = degree %% 360
if(degree > 180 & degree < 360) {
if(facing == "bending.inside") {
facing = "bending.outside"
} else {
facing = "bending.inside"
}
}
}

pin = par("pin")
usr = par("usr")

pt_per_inche1 = (usr[2] - usr[1])/pin[1]

xplot = get.cell.meta.data("xplot", sector.index = sector.index, track.index = track.index)
cell.xlim = get.cell.meta.data("cell.xlim", sector.index = sector.index, track.index = track.index)
width_in_degree = width/(cell.xlim[2] - cell.xlim[1]) * ((xplot[1] - xplot[2]) %% 360)
yplot = get.cell.meta.data("yplot", sector.index = sector.index, track.index = track.index)
cell.ylim = get.cell.meta.data("cell.ylim", sector.index = sector.index, track.index = track.index)
height_in_native = height/(cell.ylim[2] - cell.ylim[1]) * (yplot[2] - yplot[1])

r = yplot[1] + (y - cell.ylim[1])/(cell.ylim[2] - cell.ylim[1]) * (yplot[2] - yplot[1])
width_in_native = pi*as.radian(width_in_degree)*r

width_in_px = round(width_in_native/pt_per_inche1*96)
height_in_px = round(height_in_native/pt_per_inche1*96)

# resize according to the size on the image
image = resize(image, w = width_in_px*resolution, h = height_in_px*resolution)
image = as.raster(image)

# make circular rectangles
xlim = get.cell.meta.data("xlim", sector.index = sector.index, track.index = track.index)
ylim = get.cell.meta.data("ylim", sector.index = sector.index, track.index = track.index)

nr = nrow(image)
nc = ncol(image)

row_index = rep(1:nr, nc)
col_index = rep(1:nc, each = nr)

if(facing == "bending.inside") {
yv = 1 - (row_index - 0.5)/nr
xv = (col_index - 0.5)/nc
} else {
yv = (row_index - 0.5)/nr
xv = 1 - (col_index - 0.5)/nc
}
xv = x - width/2 + xv*width
yv = y - height/2 + yv*height
l = !grepl("^#FFFFFF", image)
circos.rect(xv[l] - width/nc/2, yv[l] - height/nr/2, xv[l] + width/nc/2, yv[l] + height/nr/2,
col = image[l], border = image[l], sector.index = sector.index, track.index = track.index)

} else {
if(missing(width) && missing(height)) {
stop("at least one of `width` and `height` should be specified")
}
if(!missing(width)) {
width_lt = parse_unit(width)
width = width_lt$value
width_unit = width_lt$unit
width_in_px = switch(width_unit,
mm = width*3.7795275591,
cm = width*37.795275591,
inche = width*96
)
width_in_px = round(width_in_px)
width_in_native = convert_length(width, width_unit)
}
if(!missing(height)) {
height_lt = parse_unit(height)
height = height_lt$value
height_unit = height_lt$unit
height_in_px = switch(width_unit,
mm = height*3.7795275591,
cm = height*37.795275591,
inche = height*96
)
height_in_px = round(height_in_px)
height_in_native = convert_length(height, height_unit)
}

if(missig(width)) {
width_in_px = round(height_in_px*asp)
width_in_native = width_in_native*asp
}
if(missing(height)) {
height_in_px = round(width_in_px/asp)
height_in_native = width_in_native*asp
}

df1 = circlize(x, y, sector.index = sector.index, track.index = track.index)
df2 = polar2Cartesian(df1)
x0 = df2[1, 1]
y0 = df2[1, 2]

# resize accoring to the width and height
image = resize(image, w = width_in_px, h = height_in_px)

theta = df1[1, 1] - 90
coor_mat = cbind(c(x0 - width_in_native/2, y0 - height_in_native/2),
c(x0 + width_in_native/2, y0 + height_in_native/2))

points(corr_mat[, 1], corr_mat[, 2], pch = 16, col = "red")

# since rasterImage() rotate image at the left bottom corner,
# here we move the image to let it rotate at the center of the image
rot_mat1 = cbind(c( cos(as.radian(theta)), sin(as.radian(theta))),
c(-sin(as.radian(theta)), cos(as.radian(theta))))
rot_mat2 = cbind(c( cos(as.radian(-theta)), sin(as.radian(-theta))),
c(-sin(as.radian(-theta)), cos(as.radian(-theta))))
coor_mat = coor_mat %*% rot_mat1
corr_mat[, 1] = corr_mat[, 1] - width_in_native/2
corr_mat[, 2] = corr_mat[, 2] - height_in_native/2
corr_mat = corr_mat %*% rot_mat2
rasterImage(image, corr_mat[1, 1], corr_mat[1, 2], corr_mat[2, 1], corr_mat[2, 2], angle = theta)
points(corr_mat[, 1], corr_mat[, 2], pch = 16, col = "red")
}
}


# a function convert unit in data coordinate to absolute unit

0 comments on commit b48a900

Please sign in to comment.