Skip to content

Commit 4d8ef17

Browse files
committed
add MipNeRF360 chart
1 parent f1d4856 commit 4d8ef17

1 file changed

Lines changed: 319 additions & 39 deletions

File tree

_pages/experiment_MipNeRF360.html

Lines changed: 319 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,43 +10,323 @@
1010
<link rel="stylesheet" href="{{ base_path }}/assets/css/tags.css">
1111
<script src="https://cdn.plot.ly/plotly-3.3.0.min.js" charset="utf-8"></script>
1212
<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.4.1/papaparse.min.js"></script>
13+
<script src="{{ base_path }}/assets/js/charty.js"></script>
1314
<script src="{{ base_path }}/assets/js/tags.js"></script>
14-
这是页面的介绍内容。
15-
16-
17-
18-
<ul class="custom-tabs">
19-
<li><a href="#tab1">研究方向</a></li>
20-
<li><a href="#tab2">发表论文</a></li>
21-
<li><a href="#tab3">项目经历</a></li>
22-
</ul>
23-
24-
<div class="tab-content-wrapper">
25-
<div id="tab1" class="tab-content-item">
26-
<h3>研究方向</h3>
27-
<p>这里是研究方向的内容。</p>
28-
<ul>
29-
<li>3D Gaussian Splatting</li>
30-
<li>Point Cloud Processing</li>
31-
<li>Computer Vision</li>
32-
</ul>
33-
</div>
34-
35-
<div id="tab2" class="tab-content-item">
36-
<h3>发表论文</h3>
37-
<p>这里是论文列表。</p>
38-
<ol>
39-
<li>Paper 1 - CVPR 2026</li>
40-
<li>Paper 2 - ICCV 2025</li>
41-
</ol>
42-
</div>
43-
44-
<div id="tab3" class="tab-content-item">
45-
<h3>项目经历</h3>
46-
<p>这里是项目经历。</p>
47-
<ul>
48-
<li>Project A - 2024</li>
49-
<li>Project B - 2023</li>
50-
</ul>
51-
</div>
52-
</div>
15+
16+
<ul id="scene-tabs" class="custom-tabs"></ul>
17+
18+
<div id="scene-tabs-content" class="tab-content-wrapper"></div>
19+
20+
<script>
21+
const DATASET_NAME = 'Mip-NeRF360';
22+
23+
function createSceneCharts(sceneName, containerPrefix) {
24+
if (!charty.dataManager.isInitialized()) return;
25+
26+
var subset = charty.dataManager.subset(DATASET_NAME, sceneName);
27+
28+
if (!subset || !subset.data || subset.data.length === 0) {
29+
console.warn(`No data for scene: ${sceneName}`);
30+
return;
31+
}
32+
33+
var data = subset.data;
34+
var uniqueMethods = subset.uniqueMethods;
35+
var colorMap = charty.dataManager.colorMap;
36+
var colorMapLight = charty.dataManager.colorMapLight;
37+
var gpu = subset.gpu;
38+
var times = subset.times;
39+
var uniqueDownsampling = subset.uniqueDownsampling;
40+
41+
var layout_base = charty.getThemedLayoutBase();
42+
var barStyle = charty.getThemedBarStyle();
43+
var plotConfig = {displayModeBar: false};
44+
45+
var traces1 = [];
46+
uniqueMethods.forEach((method, i) => {
47+
var row = data.find(d => d.method === method && d.downsampling == 8);
48+
if (!row) return;
49+
traces1.push({
50+
x: [method],
51+
y: [parseFloat(row.psnr_7k_train) || 0],
52+
name: i === 0 ? '7k' : '',
53+
legendgroup: '7k',
54+
showlegend: i === 0,
55+
type: 'bar',
56+
marker: {color: colorMapLight[method], line: barStyle.line},
57+
offsetgroup: '7k'
58+
});
59+
traces1.push({
60+
x: [method],
61+
y: [parseFloat(row.psnr_30k_train) || 0],
62+
name: i === 0 ? '30k' : '',
63+
legendgroup: '30k',
64+
showlegend: i === 0,
65+
type: 'bar',
66+
marker: {color: colorMap[method], line: barStyle.line},
67+
offsetgroup: '30k'
68+
});
69+
});
70+
71+
Plotly.newPlot(`${containerPrefix}-chart1`, traces1, Object.assign({}, layout_base, {
72+
title: {text: `${sceneName} - Training PSNR: 7k vs 30k (DS=8)`, font: {size: 14}, x: 0.5},
73+
barmode: 'group',
74+
xaxis: Object.assign({}, layout_base.xaxis, {}),
75+
yaxis: Object.assign({}, layout_base.yaxis, {title: {text: 'PSNR (dB)', font: {size: 12}}}),
76+
legend: Object.assign({}, layout_base.legend, {traceorder: 'grouped'})
77+
}), plotConfig);
78+
79+
var traces2 = [];
80+
uniqueMethods.forEach((method, i) => {
81+
var row = data.find(d => d.method === method && d.downsampling == 8);
82+
if (!row) return;
83+
traces2.push({
84+
x: [method],
85+
y: [parseFloat(row.psnr_30k_train) || 0],
86+
name: i === 0 ? 'Train' : '',
87+
legendgroup: 'Train',
88+
showlegend: i === 0,
89+
type: 'bar',
90+
marker: {color: colorMap[method], line: barStyle.line},
91+
offsetgroup: 'Train'
92+
});
93+
traces2.push({
94+
x: [method],
95+
y: [parseFloat(row.psnr_30k_test) || 0],
96+
name: i === 0 ? 'Test' : '',
97+
legendgroup: 'Test',
98+
showlegend: i === 0,
99+
type: 'bar',
100+
marker: {color: colorMapLight[method], line: barStyle.line},
101+
offsetgroup: 'Test'
102+
});
103+
});
104+
105+
Plotly.newPlot(`${containerPrefix}-chart2`, traces2, Object.assign({}, layout_base, {
106+
title: {text: `${sceneName} - Train vs Test PSNR (30k, DS=8)`, font: {size: 14}, x: 0.5},
107+
barmode: 'group',
108+
xaxis: Object.assign({}, layout_base.xaxis, {}),
109+
yaxis: Object.assign({}, layout_base.yaxis, {title: {text: 'PSNR (dB)', font: {size: 12}}}),
110+
legend: Object.assign({}, layout_base.legend, {traceorder: 'grouped'})
111+
}), plotConfig);
112+
113+
Plotly.newPlot(`${containerPrefix}-chart3`, [{
114+
x: uniqueMethods,
115+
y: uniqueMethods.map(m => {
116+
var idx = data.findIndex(d => d.method === m && d.downsampling == 8);
117+
return idx >= 0 ? times[idx] / 60 : 0;
118+
}),
119+
type: 'bar',
120+
marker: Object.assign({color: uniqueMethods.map(m => colorMap[m])}, barStyle),
121+
text: uniqueMethods.map(m => {
122+
var idx = data.findIndex(d => d.method === m && d.downsampling == 8);
123+
return idx >= 0 ? gpu[idx] : '';
124+
}),
125+
textposition: 'outside',
126+
textfont: {size: 9, color: charty.getCurrentTheme() === 'dark' ? '#ccc' : '#333'}
127+
}], Object.assign({}, layout_base, {
128+
title: {text: `${sceneName} - Training Time (DS=8)`, font: {size: 14}, x: 0.5},
129+
showlegend: false,
130+
xaxis: Object.assign({}, layout_base.xaxis, {}),
131+
yaxis: Object.assign({}, layout_base.yaxis, {title: {text: 'Time (min)', font: {size: 12}}})
132+
}), plotConfig);
133+
134+
var traces4 = uniqueMethods.map(method => {
135+
var yVals = uniqueDownsampling.map(ds => {
136+
var row = data.find(d => d.method === method && d.downsampling == ds);
137+
return row ? parseFloat(row.psnr_30k_train) || null : null;
138+
});
139+
return {
140+
x: uniqueDownsampling.map(d => '1/' + d),
141+
y: yVals,
142+
name: method,
143+
type: 'bar',
144+
hovertemplate: method + '<br>Factor: %{x}<br>PSNR: %{y:.2f} dB<extra></extra>',
145+
marker: Object.assign({color: colorMap[method]}, barStyle)
146+
};
147+
});
148+
149+
Plotly.newPlot(`${containerPrefix}-chart4`, traces4, Object.assign({}, layout_base, {
150+
title: {text: `${sceneName} - PSNR vs Resolution (30k)`, font: {size: 14}, x: 0.5},
151+
barmode: 'group',
152+
xaxis: Object.assign({}, layout_base.xaxis, {tickangle: 0}),
153+
yaxis: Object.assign({}, layout_base.yaxis, {title: {text: 'PSNR (dB)', font: {size: 12}}})
154+
}), plotConfig);
155+
156+
var traces5 = [];
157+
158+
uniqueMethods.forEach((method, i) => {
159+
traces5.push({
160+
x: [null],
161+
y: [null],
162+
name: method,
163+
legendgroup: method,
164+
type: 'scatter',
165+
mode: 'markers',
166+
marker: {
167+
color: colorMap[method],
168+
symbol: 'circle',
169+
size: 10,
170+
line: {color: charty.getCurrentTheme() === 'dark' ? '#666' : '#000', width: 1}
171+
}
172+
});
173+
});
174+
175+
uniqueDownsampling.forEach((ds, i) => {
176+
traces5.push({
177+
x: [null],
178+
y: [null],
179+
name: '1/' + ds,
180+
legendgroup: 'factors',
181+
type: 'scatter',
182+
mode: 'markers',
183+
marker: {
184+
color: '#666',
185+
symbol: charty.markerShapes[ds] || 'circle',
186+
size: 10,
187+
line: {color: charty.getCurrentTheme() === 'dark' ? '#666' : '#000', width: 1}
188+
}
189+
});
190+
});
191+
192+
uniqueMethods.forEach(method => {
193+
uniqueDownsampling.forEach(ds => {
194+
var methodData = data.filter(d => d.method === method && d.downsampling == ds);
195+
if (methodData.length === 0) return;
196+
traces5.push({
197+
x: methodData.map(d => parseFloat(d.gs_number) || 0),
198+
y: methodData.map(d => parseFloat(d.psnr_30k_train) || 0),
199+
legendgroup: method,
200+
showlegend: false,
201+
hovertemplate: method + ' (1/' + ds + ')<br>GS: %{x:.3s}<br>PSNR: %{y:.2f} dB<extra></extra>',
202+
type: 'scatter',
203+
mode: 'markers',
204+
marker: {
205+
color: colorMap[method],
206+
symbol: charty.markerShapes[ds] || 'circle',
207+
size: 10,
208+
line: {color: charty.getCurrentTheme() === 'dark' ? '#666' : '#000', width: 1}
209+
}
210+
});
211+
});
212+
});
213+
214+
Plotly.newPlot(`${containerPrefix}-chart5`, traces5, Object.assign({}, layout_base, {
215+
title: {text: `${sceneName} - GS Number vs PSNR (30k)`, font: {size: 14}, x: 0.5},
216+
xaxis: Object.assign({}, layout_base.xaxis, {tickangle: 0, rangemode: 'tozero'}),
217+
yaxis: Object.assign({}, layout_base.yaxis, {title: {text: 'PSNR (dB)', font: {size: 12}}}),
218+
legend: Object.assign({}, layout_base.legend, {tracegroupgap: 0})
219+
}), plotConfig);
220+
221+
var traces6 = [];
222+
uniqueMethods.forEach((method, i) => {
223+
var row = data.find(d => d.method === method && d.downsampling == 8);
224+
if (!row) return;
225+
traces6.push({
226+
x: [method],
227+
y: [parseFloat(row.train_render_times) / 60 || 0],
228+
name: i === 0 ? 'Render' : '',
229+
legendgroup: 'Render',
230+
showlegend: i === 0,
231+
type: 'bar',
232+
marker: {color: colorMapLight[method], line: barStyle.line},
233+
offsetgroup: 'Render'
234+
});
235+
traces6.push({
236+
x: [method],
237+
y: [parseFloat(row.train_optimal_times) / 60 || 0],
238+
name: i === 0 ? 'Optimize' : '',
239+
legendgroup: 'Optimize',
240+
showlegend: i === 0,
241+
type: 'bar',
242+
marker: {color: colorMap[method], line: barStyle.line},
243+
offsetgroup: 'Optimize'
244+
});
245+
});
246+
247+
Plotly.newPlot(`${containerPrefix}-chart6`, traces6, Object.assign({}, layout_base, {
248+
title: {text: `${sceneName} - Training Time Breakdown (DS=8)`, font: {size: 14}, x: 0.5},
249+
barmode: 'group',
250+
xaxis: Object.assign({}, layout_base.xaxis, {}),
251+
yaxis: Object.assign({}, layout_base.yaxis, {title: {text: 'Time (min)', font: {size: 12}}}),
252+
legend: Object.assign({}, layout_base.legend, {traceorder: 'grouped'})
253+
}), plotConfig);
254+
}
255+
256+
function createAllSceneTabs() {
257+
if (!charty.dataManager.isInitialized()) return;
258+
259+
var scenes = charty.dataManager.getScenes();
260+
261+
if (!scenes || scenes.length === 0) {
262+
console.warn('No scenes found');
263+
return;
264+
}
265+
266+
var tabsContainer = document.getElementById('scene-tabs');
267+
tabsContainer.innerHTML = '';
268+
269+
scenes.forEach((scene, index) => {
270+
var li = document.createElement('li');
271+
var a = document.createElement('a');
272+
a.href = `#scene-${scene}`;
273+
a.textContent = scene;
274+
if (index === 0) a.classList.add('active');
275+
li.appendChild(a);
276+
tabsContainer.appendChild(li);
277+
});
278+
279+
var contentContainer = document.getElementById('scene-tabs-content');
280+
contentContainer.innerHTML = '';
281+
282+
scenes.forEach((scene, index) => {
283+
var tabDiv = document.createElement('div');
284+
tabDiv.id = `scene-${scene}`;
285+
tabDiv.className = 'tab-content-item';
286+
if (index === 0) tabDiv.classList.add('active');
287+
288+
tabDiv.innerHTML = `
289+
<h3>${scene}</h3>
290+
<div id="scene-${scene}-chart1" class="chart"></div>
291+
<div id="scene-${scene}-chart2" class="chart"></div>
292+
<div id="scene-${scene}-chart3" class="chart"></div>
293+
<div id="scene-${scene}-chart4" class="chart"></div>
294+
<div id="scene-${scene}-chart5" class="chart"></div>
295+
<div id="scene-${scene}-chart6" class="chart"></div>
296+
`;
297+
298+
contentContainer.appendChild(tabDiv);
299+
});
300+
301+
scenes.forEach(scene => {
302+
createSceneCharts(scene, `scene-${scene}`);
303+
});
304+
}
305+
306+
Papa.parse(charty.sheetsUrls.MipNerf360, {
307+
download: true,
308+
header: true,
309+
complete: function(results) {
310+
charty.dataManager.init(results.data);
311+
createAllSceneTabs();
312+
313+
const observer = new MutationObserver(() => {
314+
createAllSceneTabs();
315+
});
316+
317+
observer.observe(document.documentElement, {
318+
attributes: true,
319+
attributeFilter: ['class', 'data-theme']
320+
});
321+
322+
observer.observe(document.body, {
323+
attributes: true,
324+
attributeFilter: ['class', 'data-theme']
325+
});
326+
327+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
328+
createAllSceneTabs();
329+
});
330+
}
331+
});
332+
</script>

0 commit comments

Comments
 (0)