Skip to content

Latest commit

 

History

History
310 lines (245 loc) · 9.09 KB

index.md

File metadata and controls

310 lines (245 loc) · 9.09 KB

Resume

Projects

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.16.0/d3.min.js"></script>
  • Visualizations in D3.js: An undirected force graph of players and their interpersonal relationships from Les Misérables.

<script> // Inspired by: https://observablehq.com/@d3/force-directed-graph var width = 560; var height = 315; var color = d3.scaleOrdinal(d3.schemeCategory10); d3.json("data/miserables.json").then(function(graph) { var label = { 'nodes': [], 'links': [] }; graph.nodes.forEach(function(d, i) { label.nodes.push({node: d}); label.nodes.push({node: d}); label.links.push({ source: i * 2, target: i * 2 + 1 }); }); var labelLayout = d3.forceSimulation(label.nodes) .force("charge", d3.forceManyBody().strength(-50)) .force("link", d3.forceLink(label.links).distance(0).strength(2)); var graphLayout = d3.forceSimulation(graph.nodes) .force("charge", d3.forceManyBody().strength(-3000)) .force("center", d3.forceCenter(width / 2, height / 2)) .force("x", d3.forceX(width / 2).strength(1)) .force("y", d3.forceY(height / 2).strength(1)) .force("link", d3.forceLink(graph.links).id(function(d) {return d.id; }).distance(50).strength(1)) .on("tick", ticked); var adjlist = []; graph.links.forEach(function(d) { adjlist[d.source.index + "-" + d.target.index] = true; adjlist[d.target.index + "-" + d.source.index] = true; }); function neigh(a, b) { return a == b || adjlist[a + "-" + b]; } var svg = d3.select("#graph") .attr("width", width) .attr("height", height); var container = svg.append("g"); svg.call( d3.zoom() .scaleExtent([.1, 4]) .on("zoom", function() { container.attr("transform", d3.event.transform); }) ); var link = container.append("g").attr("class", "links") .selectAll("line") .data(graph.links) .enter() .append("line") .attr("stroke", "#aaa") .attr("stroke-width", "1px"); var node = container.append("g").attr("class", "nodes") .selectAll("g") .data(graph.nodes) .enter() .append("circle") .attr("r", 5) .attr("fill", function(d) { return color(d.group); }) node.on("mouseover", focus).on("mouseout", unfocus); node.call( d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended) ); var labelNode = container.append("g").attr("class", "labelNodes") .selectAll("text") .data(label.nodes) .enter() .append("text") .text(function(d, i) { return i % 2 == 0 ? "" : d.node.id; }) .style("fill", "#555") .style("font-family", "Arial") .style("font-size", 12) .style("pointer-events", "none"); // to prevent mouseover/drag capture node.on("mouseover", focus).on("mouseout", unfocus); function ticked() { node.call(updateNode); link.call(updateLink); labelLayout.alphaTarget(0.3).restart(); labelNode.each(function(d, i) { if(i % 2 == 0) { d.x = d.node.x; d.y = d.node.y; } else { var b = this.getBBox(); var diffX = d.x - d.node.x; var diffY = d.y - d.node.y; var dist = Math.sqrt(diffX * diffX + diffY * diffY); var shiftX = b.width * (diffX - dist) / (dist * 2); shiftX = Math.max(-b.width, Math.min(0, shiftX)); var shiftY = 16; this.setAttribute("transform", "translate(" + shiftX + "," + shiftY + ")"); } }); labelNode.call(updateNode); } function fixna(x) { if (isFinite(x)) return x; return 0; } function focus(d) { var index = d3.select(d3.event.target).datum().index; node.style("opacity", function(o) { return neigh(index, o.index) ? 1 : 0.1; }); labelNode.attr("display", function(o) { return neigh(index, o.node.index) ? "block": "none"; }); link.style("opacity", function(o) { return o.source.index == index || o.target.index == index ? 1 : 0.1; }); } function unfocus() { labelNode.attr("display", "block"); node.style("opacity", 1); link.style("opacity", 1); } function updateLink(link) { link.attr("x1", function(d) { return fixna(d.source.x); }) .attr("y1", function(d) { return fixna(d.source.y); }) .attr("x2", function(d) { return fixna(d.target.x); }) .attr("y2", function(d) { return fixna(d.target.y); }); } function updateNode(node) { node.attr("transform", function(d) { return "translate(" + fixna(d.x) + "," + fixna(d.y) + ")"; }); } function dragstarted(d) { d3.event.sourceEvent.stopPropagation(); if (!d3.event.active) graphLayout.alphaTarget(0.3).restart(); d.fx = d.x; d.fy = d.y; } function dragged(d) { d.fx = d3.event.x; d.fy = d3.event.y; } function dragended(d) { if (!d3.event.active) graphLayout.alphaTarget(0); d.fx = null; d.fy = null; } }); // d3.json </script>

  • 3D computer vision tracking with the Microsoft Kinect
    • Developed 3D visualizer for Python with package pptk that renders 2 million points from the Microsoft Kinect
    • Tested unsupervised methods for understanding social behaviors
    • Worked on various models for inferring 3d kinematics from 2d images
<iframe width="560" height="315" src="https://www.youtube.com/embed/pSL2Q0v8fgA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
  • Training graph neural networks
    • Non-Euclidean relationships between data, (i.e. social graphs, citation networks) require unique approaches to embedding data so they can be visualized
    • Working through Stanford's CS224w, focused primarily on various implementations and architectures of graph neural nets in PyTorch
    • Deep learning journal club with Shuyu Wang, Lyric Doshi, Matthew Watson, and Dennis Feng
<iframe width="560" height="315" src="https://www.youtube.com/embed/Ib26lk4dvck" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Hobbies

  • Animating math with manim, initial package developed by 3b1b
<iframe width="560" height="315" src="https://www.youtube.com/embed/QMzvg8Z4-fc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<script type="text/javascript"> var margin = { top: 0, right: 0, bottom: 80, left: 80 }; var width = 622 - margin.left - margin.right; var height = 600 - margin.top - margin.bottom; // append the svg object to the body of the page var svg = d3.select("#volleyball") .insert("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + margin.left + "," + -(margin.bottom) + ")"); //Read the data d3.csv("data/aces.csv").then(function(data) { //Set Ranges for X and Y scales var xScale = d3 .scaleBand() .range([0, width]) .padding(0.2); var yScale = d3 .scaleLinear() .range([height, 0]) //Adding domain values to X and Y Scale xScale.domain( data.map(function (d) { return d.School; }) ); yScale.domain([ 0, d3.max(data, function (d) { return d.PerSet; }) ]); //X axis svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(xScale)) .selectAll("text") .attr("y", 0) .attr("x", 9) .attr("dy", ".35em") .attr("transform", "rotate(90)") .style("text-anchor", "start"); //Y axis svg .append("g") .call(d3.axisLeft(yScale)) .append("text") .text("Per Set"); //Bars var bar = svg .selectAll(".bar") .data(data) .enter() .append("rect") .attr("x", function (d) { return xScale(d.School); }) .attr("width", xScale.bandwidth()) .attr("y", function (d) { return yScale(d.PerSet); }) .attr("height", function (d) { return height - yScale(d.PerSet); }); }); </script>

Education

UC Berkeley
Bachelor of Science in Microbial Biology
GPA 3.71/4.00