 Our next speaker is a data artist and software developer at Mapbox. And before joining Mapbox, he was an artist in residence at the Exploratorium in San Francisco, which is a magical place, and a part of the Google Android team. And his work has been incredibly influential and shown at MoMA and many web and print publications. And he's particularly interested in using geographic data to understand and improve the pedestrian transit experiences in cities. So please give a warm welcome to Eric Fisher. So yeah, I wish I could talk in general about design like Mike was. But instead, I'm going to sort of talk about what I've learned through exhaustive churning through one particular kind of design, which is the making maps out of millions or billions of dots. And I guess the first point that I want to talk about is just why make maps out of dots at all? Why is this a thing? And I think that it's kind of a product of the era that we're living in where we've got zillions of devices out in the world that have GPS and have network. And they're not necessarily providing data that is meant to be, it's a report of a single event kind of thing. But when you take all of these location reports that are coming through the network as discrete points, you could have patterned out of them eventually if you put them all together. And some of this stuff is kind of straightforwardly transportation related. There's bus tracker data like Next Bus. There's data like a lot of cities now have GPS trackers on cabs. So this is a data set of where taxis were picked up passengers in Boston. There's navigation systems that have GPS logs. So here's places that people drove around in Boston. And then on the other side of it, you have kind of the more explicit for the purpose of mapping, but kind of the more on the metadata side of it than the map proper. So this is GPS logs that were contributed to make OpenStreetMap. And then you have data from inside OpenStreetMap itself. Like these are buildings in the Boston area that have addresses associated with them. So you can see for some reason parts of it are very well mapped with addresses and parts are not. And who knows what's going on there. And then you also have kind of the data exhaust side of thing where people are doing things that kind of have a side effect of having locations associated with them. So I've done a lot of work with photo location data from Flickr especially. And so here are pictures in Boston. Hero geotag tweets in Boston. And the patterns are similar but not the same. And then you also have just sort of the infrastructure kind of stuff that these remote devices can sense. This is iPhone location data that was cached as part of that bug that the iPhone had where it was storing locations in a public file. So you can see kind of where the cell phone networks are. And then there's also the kind of intentionally gathered stuff. This is Mozilla location service map where they're intentionally having anybody who wants to go around and find out where Wi-Fi networks are. They'll record that information and make it available through an API. Anyway, the thing that these all have together is that you've got a little bit of information about a lot of things rather than one big thing that we know a lot about. But if you take all these dots together and put them on a map, then you can see the patterns. Because that's kind of one of the things that people's vision is just really good at. We can take dots and we can see the patterns in them a lot better than a computer can. We are good at stipples. We are good at halftones. And I don't know why the eye works this way, but this is a power that human vision has. So I'm going to talk mostly about sort of the process of making these things. Things that I have learned in the course of doing this over the course of the past few years. And sort of an overview of methodology. I used to do a lot of this stuff in kind of a very ad hoc, weird way with generating postscript files, basically. They were just like, draw a circle here, draw a circle here, draw a circle here. And there's a lot of problems with this approach. And I was doing it because it was easy rather than because I thought it was a really good idea. And I mean, first of all, the main problem is it only gets you a single scale. There's the image rather than here's what makes sense for an overview versus here's what makes sense for a close up. There's a lot of trial and error involved because going into it, I didn't necessarily know what the right size for the dots were, how the colors would combine or anything like that. So try things over and over again until they work. And the last part of it makes the trial and error even worse because it's kind of an unoptimized approach. There's no efficient storage of the data. It's just turn through it and make the image and hope that it looked right. And if it didn't look right, turn through it again. Just sort of very linear. The more dots there are, the slower it's going to be. So the thing that finally forced me to revisit these practices and actually try to do things right was my first project with Matbox, which was this joint project with Gnip, which has just actually been acquired by Twitter. But at the time, they were the public archive of Twitter, I guess not public archive, but archive service of Twitter where they basically had the entire backlog of geotag tweets and wanted to do a joint project with Matbox to make a visualization of different aspects of the data that you could get out of there. So there was a phone brand's one. There was a language's one and also a version of the Locals and Tourists map that I had done before. And so anyway, this forced me to actually figure out how to do, first of all, maps that were meant for the web rather than the static images and how to make them work at lots of different scales. And the things that I learned in the course of doing that and things that I've done since then are embodied basically in this GitHub project that I've got going called Data Maps, which is the toolset that I have been using to make dot maps for the web. And it's got an encoding side to it where you feed data to it, and it indexes it into a file. It's got a rendering part, and it's got a couple of other tools. Not the world's greatest user interface, but that's where this stuff is. That's what I've been doing this stuff in. And I guess now I will start talking about just like the different things that I've learned in the course of this, like how to, why is that showing up? OK, good, sorry. So yeah, the different, just how to tune these things to actually make the visualizations work. So I guess the first thing I want to talk about is just about scale. Because when you're talking about data that you can either view totally zoomed in so you're looking at a single city block or zoomed out so that you're looking at the entire world, there's a lot of different scales to think about. And so as just like a starting point to think about, I should, sorry, I need to mute my phone because it's making noises. And there's kind of this nebulous idea of the human scale, which is thrown around all kinds of architectural and urban design terms, what is the natural human environment? But as far as web maps are concerned, I think the human scale is kind of zoom level 13, which is kind of a ridiculous thing to say, but it's basically the scale where a pixel on the screen is about 50 feet on a side. And that 50 feet on a side is kind of a thing that we experience as people. That size of a pixel is about the size of a building that people live in. It's about the width of a street. And so I think that if we can start off by making things work at zoom level 13, that that's kind of like make it work at the basic level of human experience. And so then the other side of it is, if you take that scale, then what do you do with the brightness as you combine dots? And I'm going to again make the assertion here that if you have something that is kind of on the scale of population, which a lot of these things are, this diagram here is explicitly census data, but a lot of these things are basically population maps in some sense. It might be sort of business focused rather than residents focused or something like that. But if you have something that's on the order of magnitude of population, then you want to make the densities work like population does. And so in this case, the places on the map where you just see the base map are places where nobody lives. The places that are kind of mid-tone color are places where there's about four people per building. And then the places that are fully bright are the places where there's about 16 people per building. And this is kind of arbitrary categories, but it also kind of corresponds to the way that people actually live. And so that's kind of, and I determined these brightness things by experiment a little bit. So I'm kind of retroactively rationalizing where these brightnesses came from. But I think that it's true. I think this is why this brightness range works. The one thing that I should mention here, instead of saying zero, four, and 16 is kind of a weird scale. Why isn't it zero, eight, and 16 so that you're having this linear range? And I don't have a great rationalization for that. I think that it's kind of a, in some sense, it's just what makes it look good. If you actually make it a linear scale, then there's a lot of places that are really dark on here. You can't see it very well. On the other hand, I may not have actually gone far enough because I was reading this research paper from Stanford that was saying that human visual perception actually perceives cube root of brightness. And so maybe this all actually should be cube root rather than square root even, that I've made everything still dimmer than it ought to be. I wish I really understood all these aspects of how vision really works. But hopefully somebody else who really understands vision can clue me in on how it really ought to be. And one thing that's actually very important about this is that if you do the linear brightness thing and you're looking at the outer scales, like country scale, world scale, you really lose all the rural areas. This is another census map. And the one on the left is linear scale and you basically, you lose everything except the major cities. But there's a lot of people who don't live in the major cities too. And if you actually wanna see kind of the qualitative things rather than just the numbers, then you need to be able to represent those parts too. So the one on the right is the square root brightness scale, which you can see the cities are much more populated than everywhere else but you can still see what's going on everywhere else too. So going the other direction, there's a question, what should happen to these dots as you zoom in? If you just zoom the pixels, then it looks like this mess and you can't tell what's going on. And if you're just zooming the size of the dots too, then it's the same kind of problem where everything is drawing on top of each other. It's too fuzzy, it's too bright. You can't really see any more detail than you could at the zoomed out version. So kind of the way that I've been doing this is instead of having a lot of dots that overlap, I've been taking the approach that as you zoom in, the dots should get bigger but not enormously bigger so that you can see increasing amounts of detail as you zoom in and then make the dots individually brighter at the same time so that they still get a little bit of a bonus brightness to them. And then the opposite thing happens as you zoom out, that if you're keeping the land area per dot constant, then as you zoom out, you basically lose everything because the density gradient for the kind of country wide scope is so much dimmer than if you're looking just within a city. And so there's also, so I also do the opposite thing in the other direction, give a brightness bump for each additional zoom level that you go out so that you can still see some places are a lot more, there's a lot more populated, a lot more active than others. The 1.6 is I have no theoretical basis for, this is purely determined by experiment of what looks good. I wish I knew what it meant, but then so hopefully somebody else has a theory for what that actually means too. And this slide is full of text and probably too much text, but it's about kind of the optimization side of it. The thing that I haven't talked about here at all is the whole billions of dots things, it's really, really slow to draw billions of dots. And if you're drawing the zoomed in tile where you really want to see every single dot, then that's fine. But if you're zooming out to the country, you really don't want to draw every dot because it's just gonna take forever to render that tile. And so the basic way of cheating on this is, for each zoom level you go out, basically drop half the dots and double the brightness to compensate. And so you still basically get the same picture because the density, there's still enough dots to compensate as you go out that it's still full, but it means that by the time you get out to the world level you still have something that's practical to do rather than trying to turn through every single person in the world to draw that one tile. And the 1.23 here is basically just by doing the math on the 1.6 from having the number of dots. Again, no theoretical basis for it, it's just what seemed to work. And now to talk more about the kind of making it work part, this is not really a beautiful slide, but there's actually a lot of kind of subtle things to get right if you're doing maps for the web in particular, because if you're making maps for the web, you're not making a big single image, you're making individual tiles that then have to fit together. And so the edges of the tiles, if you don't get things right at the edges, there will be visible seams, and it looks terrible and it's distracting. So figuring out what to do with the seams is actually a big pain. I guess one aspect of this slide is basically showing that we can't actually draw these round brushes that I've been acting like these things are made of, because we don't really have brushes, we have pixels. And depending on where these dots are located within the sub-pixel range, you end up drawing somewhere between one and four dots of different brightness to sort of approximate what this round brush is trying to look like. And then the other, and the really nasty part is what happens when the brushes are trying to draw at the edge of the tile. And this is another thing that kind of kills performance if you have a brush that sticks over the edge, you really don't know that there's a brush sticking on from some other tile unless you look at the data from the adjacent tiles too. So there's a whole lot more that you have to look up than you really ought to be able to draw your tile. It's not terrible, but it's the kind of thing that makes it not look terrible. And I cheat at the, another way that I cheat is at the levels where there's only, where it's basically pixel scale or smaller, is that I don't actually look up the adjacent tiles. It's good enough if you're just drawing a single pixel rather than trying to do the exact detail. But I feel bad about it, because it's still imprecisioned, but it's another sort of the compromise between practicality and perfection. And I also, I want to talk a little bit about color just because there are a few things that have come out of this that have really helped me. And I guess the major thing that I learned is that I kind of had this tendency to draw things that went from black to a color or white to a color. And this actually really doesn't help at all. The thing that actually makes these things look really nice and shiny is if you actually have the range go from black to white the whole way and have the color in between instead, which is, it's kind of like a sepia-toned photo or something like that, where you've got kind of a color aspect to something that is really a black to white range. But so I tend to let things fully saturate to white rather than fully saturate to a color. And the other alternative is you can use a really bright color or really, as kind of the end point where you're passing through a fairly dim color, you're going to something bright, the range is still, you're still getting a pretty big fraction of the visual range is going to use. And you can see that contrast a lot better. I should have included a slide here that used gray for the middle instead of a color because it really does just, it makes it look a whole lot more obvious that there's a range to it if you have something that has color in the middle rather than just gray. And then I also want to talk a little bit about color because most of these things that I've been showing here have been just a single color for the entire image, but often it's useful to use Hue to convey some other property of the thing. I guess the census map, the national census map had a race and ethnicity aspect to it that was using color. But the big image here is dots from the locals and tourists map and with blue for photos taken by locals, red for photos taken by tourists and they overlap a lot because it's not like there's totally separate spheres for these things. So you have to make it do something sensible when there's colors in conflict. And so the thing that I've been doing that seems to work well for this is to take, put for when there's no conflict, use of pure, purely saturated Hue. And if there is a conflict, then sort of let them average out to gray, basically. Still have the intensity that the colors would have, but don't let them actually saturate so that you can tell that there's conflict there. And then finally here is the, confessing all of the things that I did wrong as part of this. Data maps has problems. And the big one is that generating tiles dynamically really doesn't scale. If you're doing something that is a web map that's gonna be used by millions of people or something like that, it really has to be fast. It really has to be responsive. And you can't be generating dynamic bitmaps for every single person who's doing one of those requests. And especially you can't be doing it because the data format that I used ends up spreading the data for low zoom levels across the entire file rather than having it in some compact range. Which means that if you're doing, rendering tiles for the lower zoom levels that include large areas, you're basically running through the entire, every 30 second or 64th or whatever point from the file, but it's spread across the entire thing so there's no locality. You basically have to have the entire thing in memory for it to be fast, which is terrible if you have more than one dataset to work with. And then the other alternative is to not do things dynamically at all to render static bitmaps. And that's also not great because they end up being huge because if you want something that's zoomable down to the block level or something like that, each additional zoom level that you have doubles the size of the data. And so it just gets enormous. And then kind of the other more conceptual problem with it is that data is better than pictures of data. This is all about sending down to the client, here is a visual representation of a thing. But it's ultimately much better if you can actually send something that is closer to the original data so that you can do multiple interpretations on it. You can make it fully scalable. You can keep the metadata associated with it. So that it's not just here is the one representation so that it's actually going down and letting the client side do whatever is appropriate with it. So I think that ultimately the right thing to do is to, and this is sort of the direction that Mapbox has been going in general is to, we've been working on this vector tile infrastructure. Right now it's mostly used for the open street map base maps, but you can put any sort of data into it. And so I think that really the right thing to be doing is not to have a specialized rendering infrastructure, but to make tile mil two and the Mapbox vector and the Mapbox vector infrastructure be able to do all of the rendering stuff that I've been talking about in the same way so that all of this stuff can be stored as vectors rather than rasters and pass the information, pass the full information all the way down. And the big advantage of doing this is that you still have to make tiles at some level. It's not just the file that has all the data you need in it, but you don't have to render all the way down to zoom level 18 or 20 or something like that. You can do a fairly compact version that still gets all the data into a small enough form that then you've got a tile that represents, say, a neighborhood rather than a block. And you can draw the block from that neighborhood tile because all of the data is actually there. And this is also really good for the future of mobile devices, GL-based rendering, because then rather than having these static bitmap images, you've got actual data that you can work with. So first of all, it's smaller data to get down to the phone because it's just basically a few bytes per point rather than a bunch of pixels. And then also it's fully scalable. You don't have to restrict yourself to just these web power of two zoom levels. You can draw anything you want from it. So that is really all I've got as far as presentation goes. I will be happy to talk about anything else that anybody is interested in hearing about if there's any questions or anything.