增加可视化重叠段
我有一组对X点的绘制段沿x轴创建R中的自定义阅读地图的性能:增加可视化重叠段
半绘制这些任务细分市场正在决定它们的y位置,因此没有两个重叠的细分市场在同一个y水平上。对于每个片段,我从第一个位置迭代y个级别,直到到达一个不包含与当前片段重叠的片段的位置。然后记录当前分段的结束位置并移至下一个分段。
实际的代码是一个函数如下:
# Dummy data
# A list of start and end positions for each segment along the X axis. Sorted by start.
# Passing the function few.reads draws a map in half a second. Passing it many.reads takes about half an hour to complete.
few.reads <- data.frame(start=c(rep(10,150), rep(16,100), rep(43,50)), end=c(rep(30,150), rep(34,100), rep(57,50)));
many.reads <- data.frame(start=c(rep(10,15000), rep(16,10000), rep(43,5000)), end=c(rep(30,15000), rep(34,10000), rep(57,5000)));
#---
# A function to draw a series of overlapping segments (or "reads" in my along
# The x-axis. Where reads overlap, they are "stacked" down the y axis
#---
drawReads <- function(reads){
# sort the reads by their start positions
reads <- reads[order(reads$start),];
# minimum and maximum for x axis
minstart <- min(reads$start);
maxend <- max(reads$end);
# initialise yread: a list to keep track of used y levels
yread <- c(minstart - 1);
ypos <- c(); #holds the y position of the ith segment
#---
# This iteration step is the bottleneck. Worst case, when all reads are stacked on top
# of each other, it has to iterate over many y levels to find the correct position for
# the later reads
#---
# iterate over segments
for (r in 1:nrow(reads)){
read <- reads[r,];
start <- read$start;
placed <- FALSE;
# iterate through yread to find the next availible
# y pos at this x pos (start)
y <- 1;
while(!placed){
if(yread[y] < start){
ypos[r] <- y;
yread[y] <- read$end;
placed <- TRUE;
}
# current y pos is used by another segment, increment
y <- y + 1;
# initialize another y pos if we're at the end of the list
if(y > length(yread)){
yread[y] <- minstart-1;
}
}
}
#---
# This is the plotting step
# Once we are here the rest of the process is very quick
#---
# find the maximum y pos that is used to size up the plot
maxy <- length(yread);
miny = 1;
reads$ypos <- ypos + miny;
print("New Plot...")
# Now we have all the information, start the plot
plot.new();
plot.window(xlim=c(minstart, maxend+((maxend-minstart)/10)), ylim=c(1,maxy));
axis(3,xaxp=c(minstart,maxend,(maxend-minstart)/10));
axis(2, yaxp=c(miny,maxy,3),tick=FALSE,labels=FALSE);
print("Draw the reads...");
maxy <- max(reads$ypos);
segments(reads$start, maxy-reads$ypos, reads$end, maxy-reads$ypos, col="blue");
}
我的实际数据集是非常大的,并且包含最多可以有60万的区域读取,据我可以告诉。读取结果自然会堆叠在一起,因此很容易实现最糟糕的情况,即所有读取都相互重叠。绘制大量读取所花费的时间对我来说是不可接受的,所以我正在寻找一种方法来提高过程的效率。我可以用更快的东西来替换我的循环吗?有一种算法可以更快地安排读取吗?我现在真的想不出更好的方式来做这件事。
感谢您的帮助。
以贪婪的方式填充每个y级别。等级填满后,降低一级,永不回头。
伪代码:
y <- 1
while segment-list.not-empty
i <- 1
current <- segment-list[i]
current.plot(y)
segment-list.remove(i)
i <- segment-list.find_first_greater(current.end)
while (i > 0)
current <- segment-list[i]
current.plot(y)
segment-list.remove(i)
y <- y + 1
这并不一定产生在任何意义上的 “最优” 的情节,但至少它是为O(n log n)的。
你能不能对起始值进行排序吗?然后你从前到后浏览列表。对于每个项目,绘制它,然后对列表的其余部分进行二进制搜索,以查找第一个项目大于刚刚绘制的项目的结束坐标。如果没有找到,请增加Y.在绘制时删除每个项目。
排序为O(N lg N),二元搜索为O(lg N),因此总数为O(N lg N)。
好吧,听起来像这是要去的方法,谢谢! – MattLBeck 2012-03-27 10:20:19
不要紧张绘制它,你会怎么可能_interpret_有60万行的图表呢? – 2012-03-26 12:38:16
我正在编写这些地图,以手动选择我的数据区域,这些区域在其阅读的布局中具有特定的特征。如果我有很多堆叠起来的话,它们最终会被压扁成一个波浪形的矩形。在那一点上,地图仍然显示了一些东西,尽管将它变成直方图可能会更好。不过,你提到一个好点,我可能正在走一条相当不合适的道路。 – MattLBeck 2012-03-26 12:59:29