circlize icon indicating copy to clipboard operation
circlize copied to clipboard

chordDiagram not plotting arrow when direction.type includes "diffHeight" and input data frame has 2 rows

Open dcarbajo opened this issue 2 years ago • 3 comments

After much testing with chordDiagram (circlize_0.4.13), it becomes pretty obvious that it does not work as expected when the input data frame contains only 2 rows, and the direction.type parameter contains the diffHeight option.

I made a MWE to show what I mean.

I made this function first to create my circos plots (the relevant stuff is the data, palette, and direction_types):

circos_plot <- function(data, palette, direction_types, output_file, main_title){
  grDevices::png(filename=output_file, height=750, width=750)
  graphics::par(mar=c(0,0,2,0)) #bottom left top right
  circlize::circos.par(start.degree = -90, clock.wise = TRUE)
  circlize::chordDiagram(data, order = names(palette), grid.col = palette, transparency = .5, big.gap = 20,
                         annotationTrack = c("grid", "axis"), directional = 1, direction.type = direction_types,
                         link.arr.type = "big.arrow", preAllocateTracks = list(track.height = 0.09), group = NULL)
  graphics::title(main = main_title, cex.main = 2.5)
  circlize::circos.track(track.index = 1, panel.fun = function(x, y) {
    xlim = circlize::get.cell.meta.data("xlim")
    ylim = circlize::get.cell.meta.data("ylim")
    sector.name = circlize::get.cell.meta.data("sector.index")
    circlize::circos.text(mean(xlim), ylim[1], sector.name, facing = "inside",
                          niceFacing = TRUE, adj = c(0.5, -1), col= "grey40", cex = 0.9)
  }, bg.border = NA)
  circlize::circos.clear()
  grDevices::dev.off()
}

I create my base data and palette, from which I want to perform my test cases:

library(circlize)
my_data=data.frame(orig=c('orig1','orig2','orig3','orig1'), dest=c('dest1','dest2','dest3','dest4'), count=c(6,5,3,1))
colors=c('red','blue','green','yellow')
my_palette=c(colors, rev(colors))
names(my_palette)=c(my_data$orig, rev(my_data$dest))
my_palette=my_palette[-4]
direction_types=c("diffHeight", "arrows")
only_arrows="arrows"

my_data and my_palette will then look like this:

> my_data
   orig  dest count
1 orig1 dest1     6
2 orig2 dest2     5
3 orig3 dest3     3
4 orig1 dest4     1
> my_palette
   orig1    orig2    orig3    dest4    dest3    dest2    dest1 
   "red"   "blue"  "green" "yellow"  "green"   "blue"    "red" 

I run my first example case like this, which works perfectly and produces the expected output:

#CASE 1
data_to_use=my_data
palette_to_use=my_palette
output_file="test1.png"
my_title="circos test 1"
circos_plot(data_to_use, palette_to_use, direction_types, output_file, my_title)

case1

Note here I want to keep the diffHeight option, otherwise the output looks like this (which does not reflect the portion of origin observations that go into each destination):

#CASE 2
output_file="test2.png"
my_title="circos test 2"
circos_plot(data_to_use, palette_to_use, only_arrows, output_file, my_title)

test2

This following case exemplifies how subsetting the data to 3 origins connecting to 3 destinations independently, still works perfectly as expected:

#CASE 3
data_to_use=my_data[1:3,]
palette_to_use=my_palette[c(1:3,5:7)]
output_file="test3.png"
my_title="circos test 3"
circos_plot(data_to_use, palette_to_use, direction_types, output_file, my_title)

test3

Likewise, subsetting the data to just 1 origin connecting to 1 destination, still works:

#CASE 4
data_to_use=my_data[1,,drop=F]
palette_to_use=my_palette[c(1,7)]
output_file="test4.png"
my_title="circos test 4"
circos_plot(data_to_use, palette_to_use, direction_types, output_file, my_title)

test4

However, for some strange reason, the moment I subset the data to 2 rows the output does not look as expected. Note I mention 2 rows, if there are 2 origins and 3 destinations (3 rows in the data frame), it does work properly.

#CASE 5
data_to_use=my_data[1:2,]
palette_to_use=my_palette[c(1,2,6,7)]
output_file="test5.png"
my_title="circos test 5"
> data_to_use
   orig  dest count
1 orig1 dest1     6
2 orig2 dest2     5
> palette_to_use
 orig1  orig2  dest2  dest1 
 "red" "blue" "blue"  "red" 
circos_plot(data_to_use, palette_to_use, direction_types, output_file, my_title)

test5

Note how one of the arrows is missing. However, if I do not use the diffHeight option in direction_types, the arrow is plotted... But, as explained above, this is not what I want; I do need the diffHeight option to show the proportions in most of my cases.

#CASE 6
output_file="test6.png"
my_title="circos test 6"
circos_plot(data_to_use, palette_to_use, only_arrows, output_file, my_title)

test6

Note this behavior occurs as long as the data is 2 rows and the diffHeight option is used... It happens with 1 origin and 2 destinations, and with 2 origins and 1 destination.

#CASE 7
data_to_use=my_data[c(1,4),]
palette_to_use=my_palette[c(1,4,7)]
palette_to_use[2]="blue"
output_file="test7.png"
my_title="circos test 7"
circos_plot(data_to_use, palette_to_use, direction_types, output_file, my_title)

test7

#CASE 8
data_to_use[2,1]="orig2"
data_to_use[2,2]="dest1"
names(palette_to_use)[2]="orig2"
palette_to_use[2]="blue"
output_file="test8.png"
my_title="circos test 8"
circos_plot(data_to_use, palette_to_use, direction_types, output_file, my_title)

test8

Has anybody experienced anything like this and knows how to solve it? Thanks!

dcarbajo avatar Mar 07 '22 10:03 dcarbajo

@dcarbajo I am sorry I missed your post!

Yes, I can reproduce this problem. This is definitely a bug. I will fix it soon.

jokergoo avatar Jun 10 '22 08:06 jokergoo

Now it is fixed:

test5 test7 test8

jokergoo avatar Jun 10 '22 08:06 jokergoo

Many thanks!

dcarbajo avatar Jun 14 '22 07:06 dcarbajo