ShesterG commited on
Commit
003797e
1 Parent(s): 86fa6e8

consistent palette (blue=focus, red=past only); tooltip shows % + raw mean attn value

Browse files
Files changed (3) hide show
  1. app.py +3 -2
  2. reveal_widget.html +3 -3
  3. tree_widget.html +3 -3
app.py CHANGED
@@ -84,8 +84,9 @@ def build_tree(image):
84
  tree = {"g": g, "nleaves": nleaves, "maxdepth": maxdepth,
85
  "nodes": [{"id": i, "x": round(xpos[i], 3), "depth": n["depth"], "parent": n["parent"],
86
  "leaf": len(n["children"]) == 0, "n": len(n["leaves"]),
87
- "att": round(float(att_pct[n["leaves"]].sum()), 1),
88
- "attm": round(float(att_pct[n["leaves"]].mean()), 4),
 
89
  "tau": n["split_tau"], "patches": n["leaves"]} for i, n in enumerate(nodes)]}
90
  buf = io.BytesIO(); img.save(buf, "PNG")
91
  return tree, base64.b64encode(buf.getvalue()).decode()
 
84
  tree = {"g": g, "nleaves": nleaves, "maxdepth": maxdepth,
85
  "nodes": [{"id": i, "x": round(xpos[i], 3), "depth": n["depth"], "parent": n["parent"],
86
  "leaf": len(n["children"]) == 0, "n": len(n["leaves"]),
87
+ "att": round(float(att_pct[n["leaves"]].sum()), 1), # % of total attention
88
+ "attm": round(float(att_pct[n["leaves"]].mean()), 4), # mean attention % per patch (reveal order)
89
+ "attmv": round(float(att[n["leaves"]].mean()), 5), # raw mean attention value per patch
90
  "tau": n["split_tau"], "patches": n["leaves"]} for i, n in enumerate(nodes)]}
91
  buf = io.BytesIO(); img.save(buf, "PNG")
92
  return tree, base64.b64encode(buf.getvalue()).decode()
reveal_widget.html CHANGED
@@ -79,11 +79,11 @@ function renderImage(f){
79
  ctx.font=Math.round(cell*0.46)+'px monospace'; ctx.textAlign='center'; ctx.textBaseline='middle'; ctx.lineWidth=2;
80
  for(let p=0;p<P;p++){ const x=(p%G)*cell+cell/2, y=(Math.floor(p/G))*cell+cell/2;
81
  ctx.strokeStyle='rgba(0,0,0,0.85)'; ctx.strokeText(pd[p],x,y);
82
- ctx.fillStyle=pcl[p]?'#ffffff':'#ff5050'; ctx.fillText(pd[p],x,y); }
83
- // red outline of the segment currently being looked at
84
  const present=(f>=1&&f<=N)?ORDER[f-1]:null;
85
  if(present!=null){ const ps=NODES[present].patches, set=new Set(ps);
86
- ctx.strokeStyle='rgba(255,40,40,0.95)'; ctx.lineWidth=2;
87
  ps.forEach(p=>{ const r=Math.floor(p/G),c=p%G;
88
  [[r-1,c],[r+1,c],[r,c-1],[r,c+1]].forEach(([rr,cc])=>{
89
  if(rr<0||rr>=G||cc<0||cc>=G||!set.has(rr*G+cc)){
 
79
  ctx.font=Math.round(cell*0.46)+'px monospace'; ctx.textAlign='center'; ctx.textBaseline='middle'; ctx.lineWidth=2;
80
  for(let p=0;p<P;p++){ const x=(p%G)*cell+cell/2, y=(Math.floor(p/G))*cell+cell/2;
81
  ctx.strokeStyle='rgba(0,0,0,0.85)'; ctx.strokeText(pd[p],x,y);
82
+ ctx.fillStyle=pcl[p]?'#ffffff':'#cfd4e0'; ctx.fillText(pd[p],x,y); }
83
+ // blue outline of the segment currently being looked at (matches the "present" node)
84
  const present=(f>=1&&f<=N)?ORDER[f-1]:null;
85
  if(present!=null){ const ps=NODES[present].patches, set=new Set(ps);
86
+ ctx.strokeStyle='rgba(91,156,246,0.95)'; ctx.lineWidth=2;
87
  ps.forEach(p=>{ const r=Math.floor(p/G),c=p%G;
88
  [[r-1,c],[r+1,c],[r,c-1],[r,c+1]].forEach(([rr,cc])=>{
89
  if(rr<0||rr>=G||cc<0||cc>=G||!set.has(rr*G+cc)){
tree_widget.html CHANGED
@@ -47,7 +47,7 @@ function sizeImage(){
47
  // attention color (low=blue, high=orange)
48
  function attColor(a){
49
  const t=Math.min(1, a/25); // 25% saturates
50
- const c1=[91,156,246], c2=[244,162,97];
51
  return `rgb(${Math.round(c1[0]+(c2[0]-c1[0])*t)},${Math.round(c1[1]+(c2[1]-c1[1])*t)},${Math.round(c1[2]+(c2[2]-c1[2])*t)})`;
52
  }
53
  function highlight(node){
@@ -56,7 +56,7 @@ function highlight(node){
56
  ctx.fillStyle='rgba(8,10,18,0.72)'; ctx.fillRect(0,0,S,S);
57
  const set=new Set(node.patches);
58
  node.patches.forEach(p=>{ const r=Math.floor(p/G), c=p%G; ctx.clearRect(c*cell,r*cell,cell,cell); });
59
- ctx.strokeStyle='rgba(255,255,255,0.9)'; ctx.lineWidth=1.5;
60
  // outline boundary of the lit region
61
  node.patches.forEach(p=>{ const r=Math.floor(p/G), c=p%G;
62
  const nb=[[r-1,c],[r+1,c],[r,c-1],[r,c+1]];
@@ -89,7 +89,7 @@ function drawTree(){
89
  circles.forEach(el=>{
90
  const n=NODES[+el.dataset.id];
91
  el.addEventListener('mouseenter',e=>{ highlight(n);
92
- tip.style.opacity=1; tip.innerHTML=`level ${n.depth} 路 ${n.n} patches 路 ${n.att}% attn 路 ${n.attm}%/patch mean`+(n.tau!=null?` 路 splits at 蟿=${n.tau}`:' 路 leaf');
93
  });
94
  el.addEventListener('mousemove',e=>{ const b=right.getBoundingClientRect();
95
  tip.style.left=(e.clientX-b.left-tip.offsetWidth-12)+'px'; tip.style.top=(e.clientY-b.top+12)+'px'; });
 
47
  // attention color (low=blue, high=orange)
48
  function attColor(a){
49
  const t=Math.min(1, a/25); // 25% saturates
50
+ const c1=[150,158,176], c2=[244,162,97]; // attention heat: grey(low) -> orange(high)
51
  return `rgb(${Math.round(c1[0]+(c2[0]-c1[0])*t)},${Math.round(c1[1]+(c2[1]-c1[1])*t)},${Math.round(c1[2]+(c2[2]-c1[2])*t)})`;
52
  }
53
  function highlight(node){
 
56
  ctx.fillStyle='rgba(8,10,18,0.72)'; ctx.fillRect(0,0,S,S);
57
  const set=new Set(node.patches);
58
  node.patches.forEach(p=>{ const r=Math.floor(p/G), c=p%G; ctx.clearRect(c*cell,r*cell,cell,cell); });
59
+ ctx.strokeStyle='rgba(91,156,246,0.95)'; ctx.lineWidth=1.5; // blue = "focused" region
60
  // outline boundary of the lit region
61
  node.patches.forEach(p=>{ const r=Math.floor(p/G), c=p%G;
62
  const nb=[[r-1,c],[r+1,c],[r,c-1],[r,c+1]];
 
89
  circles.forEach(el=>{
90
  const n=NODES[+el.dataset.id];
91
  el.addEventListener('mouseenter',e=>{ highlight(n);
92
+ tip.style.opacity=1; tip.innerHTML=`level ${n.depth} 路 ${n.n} patches 路 ${n.att}% of attention mean attn ${n.attmv}`+(n.tau!=null?` 路 splits at 蟿=${n.tau}`:' 路 leaf');
93
  });
94
  el.addEventListener('mousemove',e=>{ const b=right.getBoundingClientRect();
95
  tip.style.left=(e.clientX-b.left-tip.offsetWidth-12)+'px'; tip.style.top=(e.clientY-b.top+12)+'px'; });