如何在R中垂直分布矩形以避免重叠(保持x坐标不变)
垂直重排矩形消除重叠(固定x坐标)
我有一组存储在R数据框中的矩形,每个矩形由xmin、ymin、xmax、ymax坐标表示,部分矩形存在重叠。需要将这些矩形绘制在图表上,仅通过垂直移动重新分布,确保任意两个矩形不重叠,同时保留矩形的x坐标不变。
原始重叠矩形示例代码
df <- structure(list(xmin = c(67.705914, 6.005184, 66.162244, 87.99481, 46.082243, 16.280928, 47, 3.4155154, 23.347187, 84.895525, 82.80274, 16.85878, 4.3557265, 6.625263, 7.626907, 96.220383, 12.115471, 30.235073, 46.082243, 16.280928, 79.90225, 29.42548, 84.895525, 23.347184, 3.198581, 7.2832146, 25.539455, 1.695044, 34.425616, 3.87074, 78.284034, 89.64427, 87.0506, 87.68941, 75.329986, 2.213225, 3.4155154, 4.6098725, 0.5424367, 80.416396, 12.115471, 6.625263, 32.722494, 8.344733, 89.64427, 52.48499, 90.12926, 30.235073, 2.9885126, 8.719267), xmax = c(73.705914, 12.005184, 72.162244, 93.99481, 52.082243, 22.280928, 53, 9.4155154, 29.347187, 90.895525, 88.80274, 22.85878, 10.3557265, 12.625263, 13.626907, 102.220383, 18.115471, 36.235073, 52.082243, 22.280928, 85.90225, 35.42548, 90.895525, 29.347184, 9.198581, 13.2832146, 31.539455, 7.695044, 40.425616, 9.87074, 84.284034, 95.64427, 93.0506, 93.68941, 81.329986, 8.213225, 9.4155154, 10.6098725, 6.5424367, 86.416396, 18.115471, 12.625263, 38.722494, 14.344733, 95.64427, 58.48499, 96.12926, 36.235073, 8.9885126, 14.719267), ymin = c(15.6854458039728, 29.280227138751, 85.6077652217337, 11.1447959143222, 88.6507847970509, 47.8780668201714, 58.249961106352, 20.7963843697899, 39.1374442773956, 14.253314246173, 31.2038928836167, 75.406238562994, 90.8407922528565, 34.3969058783788, 90.0758115822633, 47.8810408921933, 41.9826622904241, 18.4008825788269, 64.0816967514961, 26.1344753018713, 87.6969580943045, 29.8031653049004, 25.5889076966207, 24.8832114234653, 65.6939979329678, 83.7251558885676, 62.3262453418105, 52.1180170583712, 22.2274072090833, 46.6403205808079, 51.4982774017124, 52.9611597344073, 86.5149513741532, 8.71673006759099, 73.63580649852, 10.2390589604505, 79.6728413001311, 27.0399934909858, 17.2084996917785, 28.7198728007395, 27.7845507714287, 64.8898031132345, 77.518346688506, 11.785758214691, 51.2219947101639, 55.4683310942946, 59.4959604756725, 15.6990628891733, 53.6174786549635, 49.4079504426206), ymax = c(17.2907089618675, 31.2234089569328, 87.3295043521685, 13.2730010425273, 90.8437672531913, 50.9203203412982, 60.4271762962254, 23.1819265384646, 41.6096664996178, 15.6887703563279, 34.0475653401924, 77.3496347894091, 93.4576597227361, 37.1520079191952, 92.2237107419272, 52.1189591078067, 43.7265046549561, 21.6912051594721, 65.7843994541988, 28.3922072606342, 89.9154454892625, 33.7570368040767, 27.4828470905601, 26.6122436815298, 69.5273312663012, 86.1164074074011, 64.1048569740807, 55.1107177882982, 23.6523109318047, 48.9688920093793, 54.4445139608521, 55.219401492649, 88.3781992374011, 11.2337368703121, 75.7899915205464, 13.1508236663329, 85.2391063603721, 29.4730210139216, 20.1518959181936, 33.1198728007395, 30.7228223763669, 66.81402503475, 79.1315542356758, 13.8413137702466, 52.7337440574224, 57.6201635550276, 61.8678354756725, 19.1313772996537, 55.6110888786056, 51.560255051839 )), row.names = c(NA, -50L), class = "data.frame") ggplot(df,aes(xmin=xmin,xmax=xmax,ymin=ymin,ymax=ymax)) + geom_rect(color="black",fill="cyan") + theme_void()
运行上述代码会得到存在重叠的矩形图表。
尝试过的方法
- 查阅资料未找到R语言中仅垂直移动消除矩形重叠的现成方案
- 尝试使用
beeswarm包的swarmy函数随机移动矩形,但矩形数量较多时效率极低
最终解决方案代码
通过自定义重叠检测函数,逐个调整矩形的垂直位置,确保无重叠:
library(ggplot2) #' 检测单个矩形是否与矩形集合中的任意矩形重叠 #' #' @param testRect 待检测的矩形(需包含xmin、xmax、ymin、ymax属性) #' @param rectList 矩形集合数据框,需包含xmin、xmax、ymin、ymax列 #' @returns 布尔值:TRUE表示存在重叠,FALSE表示无重叠 #' overlaps_any <- function(testRect, rectList) { if(nrow(rectList)==0) { return(FALSE) } for (r in 1:nrow(rectList)) { # 面积为0的矩形不参与重叠检测 if (testRect$xmin == testRect$xmax || testRect$ymax == testRect$ymin || rectList[r,"xmin"] == rectList[r,"xmax"] || rectList[r,"ymax"] == rectList[r,"ymin"]) { next } # 水平方向无重叠则跳过 if (testRect$xmin > rectList[r,"xmax"] || rectList[r,"xmin"] > testRect$xmax) { next } # 垂直方向无重叠则跳过 if (testRect$ymin > rectList[r,"ymax"] || rectList[r,"ymin"] > testRect$ymax) { next } return(TRUE) } return(FALSE) } # 创建空数据框存储调整后的矩形 df.new <- data.frame() # 逐个处理原始数据框中的矩形 for(r in 1:nrow(df)) { # 取出当前矩形 testRect <- df[r,] # 保留矩形高度 rect_height <- testRect$ymax - testRect$ymin # 初始位置设为y轴底部 testRect$ymin <- 0 testRect$ymax <- testRect$ymin + rect_height # 循环调整垂直位置直到无重叠 while(overlaps_any(testRect, df.new)) { testRect$ymin <- testRect$ymin + 1 testRect$ymax <- testRect$ymax + 1 } # 将调整后的矩形加入新数据框 df.new <- rbind(df.new, testRect) } # 绘制无重叠的矩形图表 print( ggplot(df.new, aes( xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax )) + geom_rect(color = "black", fill = "cyan") + coord_fixed() + theme_void() )
运行该代码后可得到无重叠的垂直分布矩形图表。
内容的提问来源于stack exchange,提问作者kurpav00
相关产品推荐
相关产品推荐

