Squarified Treemaps 論文演算法復現
Squarified Treemaps
復現了論文Squarified Treemaps
的演算法,將層次結構視覺化為寬高比適宜的矩形劃分圖
GitHub完整程式碼
實驗環境
- windows10
- visual studio 2017
- opengl: GLFW
- c++
視覺化效果
使用論文中的測試資料
測試資料同論文Squarified Treemaps中樣例(按100的比例擴大),結果標註面積如圖所示(由於本次實現座標從左上角開始計算,因此行4 3
和行2 2 1
位置不同,但沒有任何影響)
- 資料:
vector<double> areas = { 60000,60000,40000,30000,20000,20000,10000 };
- 空間尺寸:
WIDTH = 600, HEIGHT = 400
實現效果
論文原圖
交換測試資料順序進行測試
為驗證矩形面積順序對視覺化效果的影響,將上述測試資料順序進行調整並檢視效果
-
資料:
{ 4,6,6,3,2,2,1 };
-
資料:
{ 4,6,2,3,2,6,1 };
視覺化思路
影像的繪製
在演算法layoutrow()
時存下當前行矩形的資訊,包括4個座標點,在GLFW的主迴圈中使用display
展示所有的矩形
演算法涉及的函式原型及資料結構
函式原型
void squarify(vector<double> children, vector<double> row, double w);
children
為還需要安置的矩形面積row
為當前行已安置的矩形面積w
為當前正在安置位置的大矩形的寬(短邊長)
double worst(vector<double> R, double w);
- 返回值:當前矩形的最差長寬比(與1之差絕對值的最大值)
R
為矩形面積列表w
為當前正在安置位置的大矩形的寬(短邊長)
void layoutrow(vector<double> R, double w);
R
為矩形面積列表w
為當前正在安置位置的大矩形的寬(短邊長)
double width(vector<double> R, int w);
- 返回值:當前空餘面積的短邊,使用全域性變數
Rwidth
和Rheight
儲存空餘矩形資訊,返回二者之間的最小值 R
為矩形面積列表w
為當前正在安置位置的大矩形的寬(短邊長)
- 返回值:當前空餘面積的短邊,使用全域性變數
資料結構
- 矩形:存放4個頂點座標
struct Rectangle {
double x1, y1, x2, y2, x3, y3, x4, y4;
};
技術實現
squarify
void squarify(vector<double> children, vector<double> row, double w) {
if (w <= 0) return;
if (children.empty()) {
if(!row.empty()) layoutrow(row, w); // output current row
return;
}
//
double c = children[0];
vector<double> newrow = row; // newrow
newrow.push_back(c);
if (worst(row, w) >= worst(newrow, w)) { // can be placed in this row
//cout << " add: " << c << endl;
vector<double> tmp(children.begin() + 1, children.end());
squarify(tmp, newrow, w);
}
else { // placed in a empty new row
layoutrow(row, w); // output current row
squarify(children, {}, width(row, w));
}
}
worst
double worst(vector<double> R, double w) {
if (R.empty()) return INF;
double rmx = 0, rmn = INF, s = 0;
for (auto r : R) {
s += r;
if (r > rmx) rmx = r;
if (r < rmn) rmn = r;
}
double pw = pow(w, 2), sw = pow(s, 2);
double res = max(pw*rmx / sw, sw / (pw*rmn));
return max(pw*rmx / sw, sw / (pw*rmn));
}
layoutrow
void layoutrow(vector<double> R, double w) {
double lx = WIDTH - Rwidth + (_WIDTH-WIDTH)/2.,
ly = HEIGHT - Rheight + (_HEIGHT - HEIGHT) / 2.; // left-top
int direction; // 0: horizontal; 1: vertical
// refresh Rwidth, Rheight
double sum = 0;
for (auto r : R)
sum += r;
double ext = sum / w;
if (abs(w - Rwidth) <= 1e-6) {
Rheight -= ext;
direction = 0;
}
else {
Rwidth -= ext;
direction = 1;
}
// store
for (auto r : R) {
if (direction == 0) {
double hh = ext, ww = r / ext;
rects.emplace_back(
transx(lx), transy(ly),
transx(lx+ww), transy(ly),
transx(lx+ww), transy(ly+hh),
transx(lx), transy(ly+hh)
);
// refresh
lx += ww;
}
else {
double ww = ext, hh = r / ext;
rects.emplace_back(
transx(lx), transy(ly),
transx(lx + ww), transy(ly),
transx(lx + ww), transy(ly + hh),
transx(lx), transy(ly + hh)
);
// refresh
ly += hh;
}
}
}
width
double worst(vector<double> R, double w) {
if (R.empty()) return INF;
double rmx = 0, rmn = INF, s = 0;
for (auto r : R) {
s += r;
if (r > rmx) rmx = r;
if (r < rmn) rmn = r;
}
double pw = pow(w, 2), sw = pow(s, 2);
double res = max(pw*rmx / sw, sw / (pw*rmn));
return max(pw*rmx / sw, sw / (pw*rmn));
}
display
void display(Color c1 = RED, Color c2 = YELLOW) {
for (Rectangle rect : rects) {
// fill in color
glLineWidth(3);
glBegin(GL_POLYGON);
glColor3f(c2.r, c2.g, c2.b);
glVertex2f(rect.x1, rect.y1);
glVertex2f(rect.x2, rect.y2);
glVertex2f(rect.x3, rect.y3);
glVertex2f(rect.x4, rect.y4);
glEnd();
// draw the border
glBegin(GL_LINE_LOOP);
glColor3f(c1.r, c1.g, c1.b);
glVertex2f(rect.x1, rect.y1);
glVertex2f(rect.x2, rect.y2);
glVertex2f(rect.x3, rect.y3);
glVertex2f(rect.x4, rect.y4);
glEnd();
}
}
總結與思考
通過本次實驗對論文Squarified Treemaps
的演算法復現,我更深刻的明白了寬高比(aspect ratio)≈1在視覺化中有更好的效果,體會到了矩形面積順序對於treemap展示的影響,同時,也對該演算法展示層級結構的不明顯理解更加深刻。
相關文章
- Split to Be Slim: 論文復現
- FCOS論文復現:通用物體檢測演算法演算法
- LEARNED STEP SIZE QUANTIZATION論文復現
- ICML 2017大熱論文:Wasserstein GAN | 經典論文復現
- 論文復現|Panoptic Deeplab(全景分割PyTorch)PyTorch
- R-Drop論文復現與理論講解
- 論文Anonymous Zether實驗復現(持續更)
- 實踐案例丨CenterNet-Hourglass論文復現
- 自監督影像論文復現 | BYOL(pytorch)| 2020PyTorch
- 論文復現丨基於ModelArts實現Text2SQLSQL
- Perceptual Losses 風格遷移論文復現小記
- 一文詳解ATK Loss論文復現與程式碼實戰
- 小白經典CNN論文復現系列(一):LeNet1989CNN
- 論文查重演算法演算法
- 經典論文復現 | 基於深度卷積網路的影像超解析度演算法卷積演算法
- 經典論文復現 | 基於深度卷積網路的影象超解析度演算法卷積演算法
- 手把手帶你復現ICCV 2017經典論文—PyraNet
- InfoGAN:一種無監督生成方法 | 經典論文復現
- COLING 2018 最佳論文解讀:序列標註經典模型復現模型
- 論文復現丨基於ModelArts進行影像風格化繪畫
- 2020西湖論劍Web復現Web
- 【跟蹤演算法】MOSSE論文翻譯演算法
- 硬幣系列三 | 硬幣自動分類的一個論文復現
- java實現論文查重Java
- 實踐心得:從讀論文到復現到為開源貢獻程式碼
- 微信團隊開源圍棋AI技術PhoenixGo,復現AlphaGo Zero論文AIGo
- 【論文】軍事理論課程論文
- 想輕鬆復現深度強化學習論文?看這篇經驗之談強化學習
- textrank-jieba 演算法復現Jieba演算法
- 論文
- 經典論文復現 | 基於標註策略的實體和關係聯合抽取
- 基於標註策略的實體和關係聯合抽取 | 經典論文復現
- PyraNet:基於特徵金字塔網路的人體姿態估計 | 經典論文復現特徵
- 論文結果圖:matplotlib和seaborn實現
- 寫論文是發現的神器網站網站
- 排隊論演算法的matlab實現演算法Matlab
- 共識演算法論文閱讀筆記1-hotstuff演算法筆記
- Stable Diffusion 3論文終於釋出,架構細節大揭秘,對復現Sora有幫助?架構Sora