Skip to content

Instantly share code, notes, and snippets.

@daaronr
Created January 9, 2026 22:28
Show Gist options
  • Select an option

  • Save daaronr/16cb1db2125c1032492f03bf8ce72eae to your computer and use it in GitHub Desktop.

Select an option

Save daaronr/16cb1db2125c1032492f03bf8ce72eae to your computer and use it in GitHub Desktop.
Cultured Meat Papers - 3D Topic Space Visualization for Unjournal PQ
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cultured Meat Papers - 3D Topic Space</title>
<script src="https://cdn.plot.ly/plotly-2.27.0.min.js"></script>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #0a0a1a 0%, #1a0a2e 50%, #0a1a2e 100%);
color: #e6edf3;
min-height: 100vh;
}
.container { max-width: 1400px; margin: 0 auto; padding: 20px; }
h1 {
text-align: center;
margin-bottom: 8px;
font-size: 1.9em;
background: linear-gradient(90deg, #00d4aa, #7ee8fa, #c9a0dc);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.subtitle { text-align: center; color: #8b949e; margin-bottom: 20px; }
#plot3d { width: 100%; height: 600px; border-radius: 12px; background: #0d1117; }
.axis-legend {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 15px;
margin-top: 20px;
background: #161b22;
border-radius: 12px;
padding: 20px;
}
.axis-box {
padding: 15px;
border-radius: 8px;
background: #21262d;
}
.axis-box h4 {
font-size: 0.9em;
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 8px;
}
.axis-box.x h4 { color: #00BFFF; }
.axis-box.y h4 { color: #FFD700; }
.axis-box.z h4 { color: #FF6B9D; }
.axis-box p { font-size: 0.85em; color: #8b949e; line-height: 1.5; }
.axis-range {
display: flex;
justify-content: space-between;
font-size: 0.75em;
margin-top: 10px;
color: #58a6ff;
}
.insights-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
margin-top: 20px;
}
.insight-card {
background: #161b22;
border-radius: 12px;
padding: 18px;
border-left: 4px solid;
}
.insight-card.cluster1 { border-color: #00d4aa; }
.insight-card.cluster2 { border-color: #ffa500; }
.insight-card.cluster3 { border-color: #ff6b9d; }
.insight-card.cluster4 { border-color: #4a9eff; }
.insight-card h4 { margin-bottom: 10px; font-size: 1em; }
.insight-card.cluster1 h4 { color: #00d4aa; }
.insight-card.cluster2 h4 { color: #ffa500; }
.insight-card.cluster3 h4 { color: #ff6b9d; }
.insight-card.cluster4 h4 { color: #4a9eff; }
.insight-card ul { margin-left: 18px; font-size: 0.9em; }
.insight-card li { margin: 6px 0; color: #c9d1d9; }
.color-legend {
display: flex;
justify-content: center;
gap: 25px;
margin-top: 15px;
flex-wrap: wrap;
}
.color-item {
display: flex;
align-items: center;
gap: 8px;
font-size: 0.85em;
}
.color-dot {
width: 14px;
height: 14px;
border-radius: 50%;
}
@media (max-width: 900px) {
.axis-legend { grid-template-columns: 1fr; }
.insights-grid { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<div class="container">
<h1>Cultured Meat Research Landscape</h1>
<p class="subtitle">Papers mapped in 3D topic space: Method × Focus × Unjournal Relevance</p>
<div id="plot3d"></div>
<div class="color-legend">
<div class="color-item">
<div class="color-dot" style="background: #00d4aa;"></div>
<span>Lab Experiments</span>
</div>
<div class="color-item">
<div class="color-dot" style="background: #ffa500;"></div>
<span>TEA / Cost Modeling</span>
</div>
<div class="color-item">
<div class="color-dot" style="background: #4a9eff;"></div>
<span>Reviews & Synthesis</span>
</div>
<div class="color-item">
<div class="color-dot" style="background: #c9a0dc;"></div>
<span>Forecasting</span>
</div>
<div class="color-item">
<div class="color-dot" style="background: #ff6b9d;"></div>
<span>High Priority (>85%)</span>
</div>
</div>
<div class="axis-legend">
<div class="axis-box x">
<h4>📊 X-Axis: Methodology</h4>
<p>From empirical lab work to theoretical modeling. Lab experiments provide ground truth; TEAs project to scale; reviews synthesize.</p>
<div class="axis-range">
<span>← Lab/Empirical</span>
<span>TEA/Modeling →</span>
</div>
</div>
<div class="axis-box y">
<h4>🔬 Y-Axis: Topic Focus</h4>
<p>From cell biology fundamentals (media, cell lines) through bioreactor engineering to full economic analysis.</p>
<div class="axis-range">
<span>← Cell Biology</span>
<span>Economics →</span>
</div>
</div>
<div class="axis-box z">
<h4>🎯 Z-Axis: Relevance Score</h4>
<p>Unjournal priority rating for the cultured meat cost/price pivotal question. Higher = more valuable to evaluate.</p>
<div class="axis-range">
<span>← Lower Priority</span>
<span>High Priority →</span>
</div>
</div>
</div>
<div class="insights-grid">
<div class="insight-card cluster1">
<h4>🧪 Cluster A: Empirical Breakthroughs</h4>
<ul>
<li><strong>Continuous manufacturing paper (91%)</strong> - Claims competitive costs achieved</li>
<li>Beefy-R albumin replacement - Demonstrates low-cost media</li>
<li>Serum-free bovine satellite cells - Practical cost reduction</li>
<li><em>Key tension:</em> Industry claims vs. academic skepticism</li>
</ul>
</div>
<div class="insight-card cluster2">
<h4>📈 Cluster B: Foundational TEAs</h4>
<ul>
<li><strong>Humbird TEA (81%)</strong> - Set the $21/kg floor estimate</li>
<li>Risner TEA - Complete production system model</li>
<li>CE Delft projections - Scenario-based futures</li>
<li><em>Key tension:</em> 2021 projections vs. 2024 cost claims</li>
</ul>
</div>
<div class="insight-card cluster3">
<h4>🔄 Cluster C: Scale-Up Focus</h4>
<ul>
<li><strong>Bioreactor scale TEA (86%)</strong> - Critical bottleneck analysis</li>
<li>Negulescu large-scale modeling (>25,000L)</li>
<li>Cell line engineering review - Overcoming growth limits</li>
<li><em>Key tension:</em> Pharma precedent vs. food-grade economics</li>
</ul>
</div>
<div class="insight-card cluster4">
<h4>📚 Cluster D: Synthesis & Forecasting</h4>
<ul>
<li><strong>Scoping review of TEAs (90%)</strong> - Meta-analysis of field</li>
<li>RP production forecasts - Limited production through 2050</li>
<li>Dullaghan & Zhang comparison - EA Forum synthesis</li>
<li><em>Key insight:</em> Reviews reveal systematic optimism bias</li>
</ul>
</div>
</div>
</div>
<script>
// Papers data: [title, method_score, topic_score, relevance, color, size, short_name]
// method_score: 0 = pure lab, 1 = pure modeling
// topic_score: 0 = cell biology, 1 = economics
// relevance: actual relevance score from CSV
const papers = [
// High-priority TEAs
["Empirical economic analysis - continuous manufacturing cultivated chicken",
0.4, 0.75, 0.91, "#ff6b9d", 22, "Continuous Mfg (91%)"],
["Scoping review of cultivated meat TEAs (Goodwin 2024)",
0.85, 0.65, 0.90, "#ff6b9d", 21, "TEA Scoping Review (90%)"],
["How much will large-scale CM cost?",
0.8, 0.85, 0.87, "#ffa500", 19, "Large-Scale Cost (87%)"],
["TEA modeling - bioreactor scale impact",
0.75, 0.7, 0.86, "#ff6b9d", 18, "Bioreactor Scale (86%)"],
// Foundational TEAs
["Humbird - Scale-up economics for cultured meat",
0.9, 0.9, 0.81, "#ffa500", 20, "Humbird TEA (81%)"],
["Preliminary TEA of animal cell-based meat",
0.85, 0.8, 0.74, "#ffa500", 15, "Preliminary TEA (74%)"],
["CE Delft - TEA future projections",
0.88, 0.85, 0.72, "#ffa500", 14, "CE Delft (72%)"],
// Lab experiments (cell biology focus)
["Beefy-R - Replacing albumin with rapeseed protein",
0.15, 0.25, 0.51, "#00d4aa", 13, "Beefy-R Albumin (51%)"],
["Serum-free medium for bovine satellite cells",
0.1, 0.2, 0.55, "#00d4aa", 12, "Serum-Free BSC"],
// Reviews and synthesis
["Cost reduction strategies for serum-free media",
0.6, 0.4, 0.60, "#4a9eff", 13, "Media Cost Review"],
["Cell line engineering review",
0.5, 0.35, 0.58, "#4a9eff", 12, "Cell Line Engineering"],
["Anticipated growth factor costs (GFI)",
0.7, 0.6, 0.50, "#4a9eff", 12, "GFI Growth Factors (50%)"],
// Forecasting
["RP - Limited CM production through 2050",
0.95, 0.8, 0.65, "#c9a0dc", 16, "RP Forecast 2050"],
["Dullaghan & Zhang TEA comparison",
0.92, 0.75, 0.55, "#c9a0dc", 14, "D&Z TEA Comparison"],
// Additional relevant papers
["Sustainable media formulations (SSRN 2025)",
0.55, 0.45, 0.62, "#4a9eff", 13, "Sustainable Media"],
["Environmental impacts - LCA (ACS 2024)",
0.7, 0.5, 0.58, "#4a9eff", 12, "LCA Environmental"],
// Lever VC analysis (recent)
["Lever VC - 2nd gen companies break through",
0.65, 0.95, 0.78, "#ffa500", 17, "Lever VC 2025"],
];
// Create traces
const x = papers.map(p => p[1]);
const y = papers.map(p => p[2]);
const z = papers.map(p => p[3]);
const colors = papers.map(p => p[4]);
const sizes = papers.map(p => p[5]);
const names = papers.map(p => p[6]);
const fullTitles = papers.map(p => p[0]);
const hoverTexts = papers.map((p, i) =>
`<b>${p[6]}</b><br>` +
`${p[0].substring(0, 50)}...<br>` +
`<br>Method: ${p[1] < 0.4 ? 'Lab/Empirical' : p[1] < 0.7 ? 'Mixed' : 'TEA/Modeling'}<br>` +
`Topic: ${p[2] < 0.4 ? 'Cell Biology' : p[2] < 0.7 ? 'Bioreactor/Scale' : 'Economics'}<br>` +
`<b>Relevance: ${(p[3] * 100).toFixed(0)}%</b>`
);
const mainTrace = {
x: x,
y: y,
z: z,
mode: 'markers+text',
type: 'scatter3d',
marker: {
size: sizes,
color: colors,
opacity: 0.9,
line: { width: 1, color: 'rgba(255,255,255,0.5)' }
},
text: names,
textposition: 'top center',
textfont: { size: 9, color: 'white' },
hovertext: hoverTexts,
hoverinfo: 'text',
name: 'Papers'
};
// Add connecting lines to show clusters
const clusterLines = {
x: [0.4, 0.85, null, 0.8, 0.75, null, 0.9, 0.85, 0.88, null],
y: [0.75, 0.65, null, 0.85, 0.7, null, 0.9, 0.8, 0.85, null],
z: [0.91, 0.90, null, 0.87, 0.86, null, 0.81, 0.74, 0.72, null],
mode: 'lines',
type: 'scatter3d',
line: { color: 'rgba(255,255,255,0.15)', width: 2 },
hoverinfo: 'skip',
showlegend: false
};
// Relevance threshold plane
const thresholdPlane = {
x: [0, 1, 1, 0],
y: [0, 0, 1, 1],
z: [0.85, 0.85, 0.85, 0.85],
type: 'mesh3d',
opacity: 0.1,
color: '#ff6b9d',
hoverinfo: 'skip',
showlegend: false
};
const layout = {
scene: {
xaxis: {
title: { text: 'Method: Lab ← → Modeling', font: { color: '#00BFFF', size: 11 } },
range: [0, 1],
gridcolor: 'rgba(255,255,255,0.1)',
tickfont: { color: '#8b949e' },
backgroundcolor: '#0d1117'
},
yaxis: {
title: { text: 'Focus: Biology ← → Economics', font: { color: '#FFD700', size: 11 } },
range: [0, 1],
gridcolor: 'rgba(255,255,255,0.1)',
tickfont: { color: '#8b949e' },
backgroundcolor: '#0d1117'
},
zaxis: {
title: { text: 'Relevance Score', font: { color: '#FF6B9D', size: 11 } },
range: [0.4, 1],
gridcolor: 'rgba(255,255,255,0.1)',
tickfont: { color: '#8b949e' },
tickformat: '.0%',
backgroundcolor: '#0d1117'
},
bgcolor: '#0d1117',
camera: {
eye: { x: 1.5, y: 1.8, z: 1.2 },
center: { x: 0, y: 0, z: -0.1 }
},
aspectratio: { x: 1, y: 1, z: 0.8 }
},
paper_bgcolor: '#0d1117',
plot_bgcolor: '#0d1117',
margin: { l: 0, r: 0, t: 30, b: 0 },
showlegend: false,
annotations: [{
x: 0.5,
y: 1.02,
xref: 'paper',
yref: 'paper',
text: '🔄 Drag to rotate | Scroll to zoom | Double-click to reset',
showarrow: false,
font: { size: 11, color: '#8b949e' }
}]
};
Plotly.newPlot('plot3d', [mainTrace, clusterLines, thresholdPlane], layout, {
responsive: true,
displayModeBar: true,
modeBarButtonsToRemove: ['toImage', 'sendDataToCloud', 'tableRotation'],
displaylogo: false
});
// Add animation on load
Plotly.animate('plot3d', {
layout: {
scene: {
camera: {
eye: { x: 2, y: 1.5, z: 1.3 }
}
}
}
}, {
transition: { duration: 2000, easing: 'cubic-in-out' },
frame: { duration: 2000 }
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment