Go to my webpage >

Wednesday, January 16, 2013

Preparing for Frugal February

As a Senior in college, I have been increasingly interested in personal finance in the past couple months. Especially so because I know I have (or hopefully, had) a spending problem. Not having to pay rent or insurance out of my own pocket as a student, seeing a lump sum in my checking account from my summer internship or part-time work during school would always get me thinking about what wonderful things I could buy with it. Regardless of whether I have $30 or $1000 in my checking, I would find a way to decimate it before the month was over. Facebook and Google knew this problem and taunted me with online shopping ads everywhere.

I read about Frugal February on Reddit, and decided to do it. This was in December. It was perfect: I would use December and January to prepare myself for this personal challenge and discover how much I could be saving if only I were more aware of my spendings.

Since there are exactly 28 days in February this year, it is perfect to split it into 4 weeks. Each week gets its own Frugal February Checklist I made:


But of course, one can't just jump into Frugal February without having planned for it. It would be like going from eating 5000 calories each day to starving for an ill-planned diet. Which would result in general unhappiness and a yoyo back to 5000 calories afterwards.

So here is a list of things I did in preparation for Frugal February in the past month and a half. Most knowledge came from /r/frual and /r/personalfinance. After watching a few lectures on Coursera for personal finance and for this 1-unit class called Financial Literacy at Stanford, I realized that the personal finance I learned from poking around Reddit was much richer and more helpful.

Get a hold of my spending habits


So everything I read on personal finance told me I should start out by finding out how and how much I'm spending money before I could make a realistic budget for myself.

At first I started writing stuff in a journal, by hand. But for some reason that didn't work. I would forget about something, or leave something out, and would be too lazy to find out when or how much. So, against the voice in the back of my head telling me Excel is not badass (probably planted there by friends from Addepar whose goal is to eliminate inefficient Excel use in the financial sector), I made an Excel spreadsheet:


And it wasn't so bad after all! I have a difficult time keeping track of receipts, and I rarely use cash, so I would just log on to online banking, check the recent transactions, and organize them in my spreadsheet every now and then.

On December 25th, I faced the moment of truth, and it was pretty awful:


Why the hell did I spend $562.42 on shopping and gifts? $123.13 on entertainment? And, why, even though I could have eaten at home, where I'm currently living with my mom and sister who are visiting from Korea for a year, I spent $416.67 eating out?

I was living like a King when I was just a student with no savings and a monstrous tuition debt I would need to pay off. Good to know!

Split accounts


The first thing that I was advised to do (by Reddit) was split my accounts. This would accomplish two goals:

1. Manage my cash flow more transparently
2. Put money away where it's not just a click away

I used to only use a checking and a savings account with the Stanford Federal Credit Union, but transferring money between the two was so easy and instantaneous that I would never accrue any money in the savings account. (Or the checking account, for that matter)

I went with Reddit and Mint's suggestion and opened up several savings accounts with Ally Bank, where there is no minimum deposit, no fee, and a 0.95%. I also set up a checking account where I plan to deposit a certain amount every month and make it so that all my bills are paid from there. Appropriate nicknames were given:


Er.. the 100K House was sort of spur of the moment and I might make it something else, however; if I had 100K I would rather invest it than have it sit in a savings account.

Set up direct deposit


The next step would be to set up direct deposit so that I wouldn't be tempted to keep more money in my spending account. I figured that if I cut back on gifting, shopping, and eating out, I could live within $400 per month. Bill pay would get a separate $100 per month for phone bills, Dropbox, and Netflix. I get paid biweekly, so this is the direct deposit form I ended up submitting:


Anything over the $500 I allocated for myself would be deposited in a savings account with Ally, after which I would distribute over the different saving goals depending on the amount of money deposited.

Write and share


The best thing to keep myself motivated was to write about it, and share my plans with friends. I found myself a forum where people share their budgets. It's a Korean website, so most of you won't be able to share, but for those who can read and write Korean, it is 대학생 재테크 카페. That, and I convinced several of my friends to join in on Frugal February!

There are still two full weeks left before February 2013, so it's not too late to start planning. Take this badge and link it to keep up with Frugal February updates!




Tuesday, January 15, 2013

D3GL Tutorials 03: Intro to data primitives with Points

Data primitives for D3GL are the visual equivalents to the raw data. So far, we have covered (1) creating a globe, (2) binding the globe to some data to set globe-specific properties, and then (3) binding primitives to data. But all this has been setting grounds for showcasing the data through the primitive it has been bound to by letting the data dictate specific properties of the primitives.

In D3GL globe, there are five data primitives:
Points, Shapes, Bars, Arcs,
and
Painter
. We will take
Points
as an intro to primitives.

Customizing primitives for data


Just as each globe was an instance of a globe template which was tied to each data element, each point, shape, arc, etc. is an instance of a template. Just like with the globe template, you will either pass in fixed values that are shared across all instances or functions that will return customized values depending on the data element it takes as argument.

Let's take
Points
as an example. First you would create a template that binds to data, as the following:
var points = globe.points()
  .data(function(k) {
    return datasets[k];
  });
As we discussed in the previous tutorial, the argument
k
is bound on the globe level (i.e. per globe) and in this case is being used as the key to fetch a dataset, which is then bound to the primitive
Points
.

We want to customize each point instance so that it represents each data element:
var points = globe.points()
  .data(function(k) {
    return datasets[k];
  })
  .radius(function(d) {
    return scaleRadius(d['precipitation']);
  })
  .color(function(d) {
    return scaleColor(d['precipitation']);
  })
  .latitude(function(d) {
    return d['latitude'];
  })
  .longitude(function(d) {
    return d['longitude'];
  });
The parameter
d
used in the setter functions represents a data element in the dataset bound to
Points
. In the above code snippet, the radius and color of each point is determined by the value of
d['precipitation']
. The scaling functions
scaleRadius
and
scaleColor
take the precipitation value and spit out an appropriately scaled radius in units of degrees, and color in "#" format. D3.js provides a convenient
d3.scale
that is pretty useful for all types of scaling, including color gradients.

Demo


This demo marks the landings on Mars with
Points
, using the color and size of each point to represent how recent the landing was: Landings on Mars

Implementation


As discussed in the previous tutorial, a data primitive for D3GL Globe is another closure within the
d3.gl.globe
closure.
Points
has a rendering function, but unlike with the globe, this function is not invoked by the client. Instead, when
Points
are added to the globe, the rendering function for
Points
is pushed to the array of rendering functions that are called per frame by
d3.gl.globe.


In the rendering loop invoked with
.call(globe),
a hidden canvas element that is programmatically created is passed in to the rendering functions for primitives, along with the datum the globe instance is bound to, and the WebGL environment:
// In rendering loop - called once per frame
for(var i = 0; i < primitiveRenderingFunctions.length; i++){
  primitiveRenderingFunctions[i](
    webGLEnvironment, contextForHiddenCanvas, datumForGlobeInstance
  );
}
Of course, it's JavaScript, not Objective-C, so the variable names are not actually this long.

In the rendering loop for
Points,
the datum pass in is used to fetch the dataset. Then for each element in the dataset, a circle is drawn using
drawCircle()
on the context that is passed in:
function points(gl, context, datum) {
  var dataset = fnData(datum);
  for (var i = 0; i < dataset.length; i++) {
    var elem = dataset[i];
    // client-defined functions are used to fetch properties of each point
    var lat = fnLat(elem);
    var lon = fnLon(elem);
    // ... and so on
    drawCircle(context, plat, plon, pradius, color, strokeColor, lineWidth);
  }
}
After all rendering functions in queue are called and the overlay texture on the hidden canvas is complete, the entire scene is rendered via
gl.renderer.render(gl.scene, gl.camera);


The other primitives roughly use the same format, but there are differences. So stay tuned!

← Prev

Sunday, December 30, 2012

The other Avatar is racist too

My sister and I used to avidly follow the Nickelodeon series Avatar: The Last Airbender. She was 9 and I was 19 but it worked out. When the movie for the series was announced, it was supposed to be titled Avatar and I was so excited I literally counted down the days - so excited that I watched the trailer for Avatar and saw suspicious looking blue people and a lot of helicopters but assumed that they decided to take the ethnic kungfu thing really seriously and very far out. I still thought that I was watching Avatar: The Last Airbender in the theater 15 minutes into the suspicious 3d movie full of tall blue people.

Er.. turns out that Avatar: The Last Airbender decided to change names to The Last Airbender because Avatar was such a big hit. No matter. I counted down the days again and this time no one wanted to go see the movie with me because no one my age was a fan of the Nickelodeon series. So I went to the theater alone, 20 minutes early, bought a popcorn and coke for myself and watched the movie, and walked out sad, disappointed, and alone in a sea of chattering children a couple hours later.

So my sister and I were rummaging around Netflix around 1am and found The Last Airbender and I decided to give it another shot - the last time I watched it was two and a half years ago, maybe I'll like it more this time around.

Nope.

The only good part about the movie was the ramen we inhaled while watching it. After we finished the movie, we watched the first episode of the original Nickelodeon series, and it was so good.

The core problem with the movie was that they swapped out all the non-white actors into white actors who made Kristen Stewart look like she deserves an Oscar.

Aang is clearly an Asian monk hero:


The real Aang should have looked something like the left drawing below, complete with the playful, childlike expression. In the movie, he is as shown in the next picture, complete with an all-too-serious face for a 12-year-old and very distinctly Caucasian features.



Now these kind of jokes don't even make sense:




In addition to changing the race of the hero of the story, they swapped out all the Inuit tribespeople too! Aang's closest friend Katara is unmistakably brown in the original series, while in the movie, she is decidedly white.

  

Even when they did cast Asian people, they casted the wrong type of Asians! Prince Zuko is clearly of Chinese descent in the original series. The people in the Fire Kingdom even have Chinese names, such as General Zhao. But they decided that Fire Kingdom citizens should be Indian. Except for Prince Zuko's uncle, who is Caucasian for some incomprehensible reason.



I've been a fan of Dev Patel long before he hit it big with Slumdog Millionaire, but it does not change the fact that he's not the right type of Asian for Avatar.

Apparently draining heros of color has been happening in Hollywood for a long time. I just found out that the movie 21 was actually based on a book that has an Asian American protagonist that defies stereotypes, but the director decided to cast a white person instead, killing all the second-generation Asian immigrant aspect of the storyline.

I felt like the following talk captured the essence of the problem:


It's so weird. At Stanford, I never feel stereotyped or marginalized as an Asian. And then I see some ridiculous things happening like The Last Airbender and 21 that people are oblivious to, and I suddenly feel unwelcome here. But I guess Stanford just spoils you like that. It doesn't hurt that there's this trend for shiny new Asian-named buildings on campus either.

If Hollywood ever goes through with making Snow Crash into a movie and turns Hero Protagonist - the half-Black, half-Korean hero of the novel who practices Japanese-style sword-fighting - into a white male that is "easy on the eyes," it will be a very, very sad day.


Friday, December 28, 2012

D3GL Tutorials 02: Binding data to each globe

So far we have discussed binding a dataset to a globe-rendering template, then creating multiple globes that utilize the template. But you also want to bind datasets per globe - you want color-coded maps, points, bars with different heights jutting out of the sphere, arcs stretching across oceans.

The elements of data - points, bars, etc. - we call data primitives. With
d3gl.globe
, we bind data per type of data primitive. That is, each globe can have multiple data primitives, and each data primitive type gets its own dataset to visualize. We will talk more about data primitives, their shared properties, and available user interactions in the next tutorial.

In this tutorial, we go over how you bind a different dataset to a data primitive on each globe.

Bind data to a primitive


var rainfall = [10, 0, 5, 20];
globe.points().data(rainfall);

In the above snippet of code, the variable
globe
is a globe template. We are creating the points layer on top of the globe, and telling it that a point should be rendered per data item in
[10, 0, 5, 20]
.

But let's not forget that the same globe template can be used to create multiple globes. With the above code, each globe rendered from the globe template will render points using the same dataset. We probably don't want that.

Bind different data to each globe


To pass in different datasets for globes using the same template, we can do the following:
var precipitation = {
  ‘rainfall’: [10, 0, 5, 20],
  ‘snowfall’: [0, 30, 0, 10]
};

// create a globe rendering template
var globe = d3.gl.globe()
  .width(300)
  .height(300)
  .texture("earth.jpg");

// add points, specify dataset for points
var points = globe.points()
  .data( function(d) {
    return precipitation[d];
  });

// render two globes
d3.select(“body”)
  .selectAll(“span”)
  .data(Object.keys(precipitation))
  .enter()
  .append(“span”)
  .call(globe);

This binds the array
['rainfall', 'snowfall']
to the globe rendering template with
.data(Object.keys(precipitation))
. Then each element in the array is passed in as a parameter to each of the two globes that are created with the template.

Because we added the
points
primitive to the globe template, each globe instance renders a points layer. The points on the globe that has the data element
'rainfall'
binds to the array
[10, 0, 5, 20]
, which it grabbed with its
data
property, as specified in the template:
.data( function(d) {
  return precipitation[d];
});

Likewise, the globe that is passed in
'snowfall'
binds its points to
[0, 30, 0, 10]
.

Demo


Since we haven't given
points
enough settings to be able to display the data, there will be no demo for this tutorial. To check out data-binding in action, you should continue on to the next tutorials that cover the different primitives you can bind data with!

Implementation


Like
d3.gl.globe
, the data primitives are closures with getters and setters. They have a rendering call, just like
d3.gl.globe
has a rendering call that is invoked with
.call(globe)
. But the rendering call for a data primitive type is invoked internally in the rendering loop started when the globes are rendered. Each rendering call for a primitive gets the data element assigned to the globe the primitive belongs to, which is then used to grab the relevant dataset.

The implementation for data primitives will be discussed more in depth in the next tutorial.

← Prev

Worrymouse

Staying home for the holidays, I spent a lot of time with my mom.
She inspired me to draw this little piece:
































































Thursday, December 27, 2012

A Romantic Brain

Dissecting Love


How on earth are you ever going to explain in terms of chemistry and physics so important a biological phenomenon as first love?
- Albert Einstein
I have long been fascinated by the mechanisms of romantic love. Why does my romance feel so unique and intense, only to realize that the same feelings have been documented world-wide for as long as writing has existed?

Some may say that dissecting love into what it really is - a chemical process in the brain and in the body - is unromantic, cold-hearted, sacrilegious. But I think it simply adds to the wonder: Earth remains awe-inspiring even after we learn that it is but one of a myriad planets in existence; water does not stop quenching our thirst because we know that it is but an amalgamation of tiny particles strewn together not unlike lego pieces; love is no less beautiful with the discovery that it is but a serious of reaction firing in our cells.


Earth is even more awe-inspiring when seen from the moon, despite - or because of - how
the view shows you that Earth is not the center of the universe


Is passionate romantic love really a uniquely human feature? I have learned to be wary of anything being described as "uniquely human." The more I learn, the more it seems as though we are nothing special compared to the rest of the universe. And yes, passionate love exists in other species, if you define passionate love as an uncontrollable, burning desire to be with a particular someone, including sexual desire but more the need to be together as companions.



Prairie voles develop lifelong bonds between mates


Of course, romantic passion observed in animals vary in how long it lasts, from mere seconds in rats, two weeks in foxes, and a lifetime in wolves. But after all, so does love between people, as Violetta puts it as she sings in Verdi's opera La Traviata: "Let's live for pleasure alone, since love, like flowers, swiftly fades."


A Romantic Brain


This series of posts will cover how romance looks in the brain, and how it alters the body and mind of those affected. Unlinked titles are yet to be written:


The romantic instinct

... talks about the different hormones involved with romance
as a basic human instinct, not unlike drives such as hunger, thirst, and lust.



Manipulating love

... discusses various ways love is and can be manipulated - how various behaviors,
circumstances, and substances can lead to romance or heartbreak.



Love as a maleable emotion

... brings up the nurture aspect of love - the emotional aspect of love
that may play a large role in humans but not in animals.


D3GL Tutorials 01: Creating globes

d3.gl.globe
is one of D3GL's data visualization templates that is useful for visualizing global, location-based data. 2D projections of the globe pose problems of distortion and misrepresentation. To take a simple, common example, a Mercator projection of the world's countries has a large “lie factor”, because countries like Greenland and Russia appear much larger than they actually are.

3D visualization has a lie factor of one. Through projection, rotation, zooming, etc, 3D visualization leverages the human brain's powerful faculties for understanding spatial data. Flight paths, for instance, make much more sense when depicted on a three-dimensional Earth because the best paths fit the curve of the Earth, which may look strange and arbitrary on a flat projection of the world. Stellar bodies other than the Earth may also benefit from three- dimensional visualizations, particularly because unlike the world map, most viewers are not familiar with flat maps of the sun, moon, Mars, and more.

D3GL's globe template can overlay the following data primitives:
points, painter, arcs, bars, shapes
. In this tutorial, we will focus on rendering naked globes without any overlays using custom globe templates.

Creating a globe template


Before you can render a globe or several, you need to create a globe template and set its properties using chaining, as in
D3.js
:
var globe = d3.gl.globe()
  .width(300)
  .height(300)
  .texture("earth.jpg");

The globe template serves as a rendering template for multiple globes. For properties shared among all globes, static values can be passed in, as in the width, height, and texture calls in the above snippet of code.

Customizing per globe


To configure a specific property per globe, a function is passed in as argument, as in the texture call in the modified code below:
var globe = d3.gl.globe()
  .width(300)
  .height(300)
  .texture(function(d) {
    return "../" + d + ".jpg";
  });

The function passed into the texture call has a parameter
d
, which refers to the data element that is passed in per globe once data is bound to the globe template. In this code example, each data element can be used to create a path for a texture for each globe.

Binding data to the globe template


The globes can be rendered by binding data, appending DOM elements to contain them, and calling globe, which refers to the object previously initialized with a call to
d3.gl.globe()
:
var data = ['earth', 'moon'];

d3.select("body").selectAll("span")
  .data(data)
  .enter()
  .append("span")
  .call(globe);

This is analogous to the
D3.js
style for adding elements bound to data. The above code will pass the bound data, which is the array
['earth', 'moon']
, when it invokes
.call(globe)
.

Then for each element in the data that is passed in, a new D3
globe
object is created to be rendered on screen. Each element in the data array will be passed in as argument. In this example, the first globe is passed in
'earth'
and the second
'moon'
, which are used to determine the texture of each globe.

Demo


Hello Earth

Implementation


The conventions for this API were inspired by Michael Bostock's essay “Toward Reusable Charts,” which encourages the use of closures with getter and setter methods and outlines specific design patterns. Thus
d3.gl.globe
is a closure with properties such as
width, height, texture, transparency, zoom, and rotation.
It supports method chaining, which means each setter returns the closure.

When
.call(globe)
is invoked, a function is called for each data element in the bound data that evaluates the appropriate values for the properties of the globe -
width, height, texture, transparency, zoom, rotation
.

WebGL is initialized once per globe using Three.js. Unlike D3.js, the render function is is called 60 frames per second using RequestAnimationFrame. Since each property of the globe is evaluated per frame, any change will be reflected immediately.

← Prev    Next →

D3GL Tutorials 00: Getting started

In this tutorial, we will go over how to incorporate D3GL into your webpage.

Linking D3GL


To get started with D3GL, first download D3GL here, by right-clicking the link and choosing "Save as..." or something similar.

Alternatively, you can add the following line between
<head>
and
</head>
:
<script type="text/javascript" src="http://dcpos.ch/d3gl/js/d3gl.min.js"></script>

I will keep the above links updated, but keep in mind that D3GL is under heavy development, so the latest (un-minified) version lives here on Github.

Running a local server


When you are developing locally, your browser may raise something along the lines of
XMLHttpRequest cannot load the url Origin null is not allowed by Access-Control-Allow-Origin
when you try to read files out of the local file system. To avoid this, you can run a local web server. I find that a simple solution is to run Python's built-in server:
python -m SimpleHTTPServer 8888 &

... after which you can access
http://localhost:8888/
.

If you are using a Mac, I find that MAMP works beautifully.

Using D3GL


Now that you have linked D3GL and run a local server, you can use
d3.gl.globe
in your code:
<script type="text/javascript">
$(function(){
  // use d3.gl to create a beautiful visualization
});
</script>

Next →

Saturday, December 15, 2012

D3GL Tutorials

My friend Daniel Posch and I created D3GL as a final project for CS 448B at Stanford, a course titled Data Visualization. Our motivation stemmed from when we were working on an interactive visualization assignment that involved using raw WebGL. It was painful. We decided that it shouldn't be so.

D3GL is a D3 plug-in library that lets users control WebGL elements and bind data in an intuitive way. WebGL is a powerful but unwieldy Javascript library, the only way to do hardware- accelerated 3D rendering in the browser. It is a thin wrapper on a low-level C API called OpenGL ES. D3GL abstracts away the setup and provides the user with a streamlined interface to render and manipulate data visualizations. It currently supports interactions including zoom, rotation, and selection with various data primitives such as points, user-defined overlays, shapes, and bars on globes.


D3GL is under heavy development at the moment, and you can check out the most recent developments at http://github.com/jiwonkim/d3gl.


You can check out the official D3GL site at http://d3gl.org.

Check out D3.js, the library that D3GL builds on top of, at http://d3js.org.

These tutorials for D3GL are aimed for people familiar with JavaScript, HTML, and CSS, although experience with D3 is unnecessary. The tutorials will cover the following:




As more data visualization types and primitives are added to D3GL, the list will grow. Existing tutorials will be linked - unlinked tutorials are yet to be written.


In addition to explaining basic D3GL concepts and usages, these tutorials will also discuss the internal implementation of each feature for those who are interested in adding to the open-source development of D3GL.