how quick can we be? data visualization techniques for engineers
TRANSCRIPT
How quick can we be? (data visualization techniques for engineers)
Who we are
Who we are
Alice Bonhomme-Biais
Who we are
Alice Bonhomme-Biais Avni Khatri
DATA
OUR PROCESS
Goals
Goals1. Plot the number of people at each location
Goals1. Plot the number of people at each location
2. Plot the percentage of women at each location
Goals1. Plot the number of people at each location
2. Plot the percentage of women at each location
3. Plot two dimensions
Goals1. Plot the number of people at each location
2. Plot the percentage of women at each location
3. Plot two dimensions
4. Clearly show the gender disparity
Goals1. Plot the number of people at each location
2. Plot the percentage of women at each location
3. Plot two dimensions
4. Clearly show the gender disparity
5. Use the tool to visualize data for future RHoKs
OPENHEATMAP
OpenHeatMap Demo
TOOLS
Non-programmatic tools
Non-programmatic tools• OpenHeatMap
• Google Fusion Tables
• Google Charts
• Socrata
• ChartsBin
• Factual
Non-programmatic tools• OpenHeatMap
• Google Fusion Tables
• Google Charts
• Socrata
• ChartsBin
• Factual
Non-programmatic tools• OpenHeatMap
• Google Fusion Tables
• Google Charts
• Socrata
• ChartsBin
• Factual
Programatic tools
Programatic tools• Google Maps JS API
• Yahoo! Maps Web Services
• Bing Maps AJAX Control
• Google Charts Tools
GOOGLE FUSION TABLES
Fusion Tables Demo
SOCRATA
GOOGLE MAPS API
function initialize() { var latlng = new google.maps.LatLng(41.850033, -87.6500523); var myOptions = { zoom: 3, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP };
var map = new google.maps.Map( document.getElementById("map_canvas"), myOptions); }
function initialize() { var latlng = new google.maps.LatLng(41.850033, -87.6500523); var myOptions = { zoom: 3, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP };
var map = new google.maps.Map( document.getElementById("map_canvas"), myOptions); }
function initialize() { var latlng = new google.maps.LatLng(41.850033, -87.6500523); var myOptions = { zoom: 3, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP };
var map = new google.maps.Map( document.getElementById("map_canvas"), myOptions); }
var locations = [ ["Aarhus, Denmark",56.162939,10.203921,10,20], ["Bangalore, India",12.971599,77.594563,217,11.98], ["Chicago, Illinois",41.878114,-87.629798,107,31.78], ["Nairobi, Kenya",1.283333,36.816667,33,6.06].......];
var locations = [ ["Aarhus, Denmark",56.162939,10.203921,10,20], ["Bangalore, India",12.971599,77.594563,217,11.98], ["Chicago, Illinois",41.878114,-87.629798,107,31.78], ["Nairobi, Kenya",1.283333,36.816667,33,6.06].......];
// add call to setMarkers in initialize function initialize() { ... setMarkers (map, locations); }
function setMarkers(map, markers) { ...
for (var i = 0; i < markers.length; i++) { markerLatLng = new google.maps.LatLng(markers[i][1],markers[i][2]);
marker = new google.maps.Marker({ position: markerLatLng, map: map, title: markers[i][0], zIndex: 1 ); } }
// add call to setMarkers in initialize function initialize() { ... setMarkers (map, locations); }
function setMarkers(map, markers) { ... for (var i = 0; i < markers.length; i++) { markerLatLng = new google.maps.LatLng(markers[i][1],markers[i][2]);
marker = new google.maps.Marker({ position: markerLatLng, map: map, title: markers[i][0], zIndex: 1 ); } }
// add call to setMarkers in initialize function initialize() { ... setMarkers (map, locations); }
function setMarkers(map, markers) { ... for (var i = 0; i < markers.length; i++) { markerLatLng = new google.maps.LatLng(markers[i][1],markers[i][2]);
marker = new google.maps.Marker({ position: markerLatLng, map: map, title: markers[i][0], zIndex: 1 ); } }
function setMarkers(map, markers) { for (var i = 0; i < markers.length; i++) { ...
iwContent = "<span class=\”label\”>" + markers[i][0] + "</span><br/>" + "Number of People: " + markers[i][3] + "<br/>" + "% of Women: " + markers[i][4];
marker = new google.maps.Marker({ ... html: iwContent });
google.maps.event.addListener(marker, "click", function() {
infowindow.setContent(this.html); infowindow.open(map, this); }); } }
function initialize() { ... infowindow = new google.maps.InfoWindow({ content: "loading..." }); }
function initialize() { ... infowindow = new google.maps.InfoWindow({ content: "loading..." }); }
function setMarkers(map, markers) { for (var i = 0; i < markers.length; i++) { ...
iwContent = "<span class=\”label\”>" + markers[i][0] + "</span><br/>" + "Number of People: " + markers[i][3] + "<br/>" + "% of Women: " + markers[i][4];
marker = new google.maps.Marker({ ... html: iwContent });
google.maps.event.addListener(marker, "click", function() {
infowindow.setContent(this.html); infowindow.open(map, this); }); } }
function setMarkers(map, markers) { for (var i = 0; i < markers.length; i++) { ...
iwContent = "<span class=\”label\”>" + markers[i][0] + "</span><br/>" + "Number of People: " + markers[i][3] + "<br/>" + "% of Women: " + markers[i][4];
marker = new google.maps.Marker({ ... html: iwContent });
google.maps.event.addListener(marker, "click", function() {
infowindow.setContent(this.html); infowindow.open(map, this); }); } }
function initialize() { ... infowindow = new google.maps.InfoWindow({ content: "loading..." }); }
<script src="http://gmaps-utility-library.googlecode.com/svn/trunk/markerclusterer/1.0/src/markerclusterer.js"></script>
var data = {"count": 232,"participants": [ { "location": "Aarhus, Denmark", "gender": "Female", "latitude": "56.162939", "longitude": "10.203921" }, { "location": "Aarhus, Denmark", "gender": "Female", "latitude": "56.162939", "longitude": "10.203921" }......]};
var data = {"count": 232,"participants": [ { "location": "Aarhus, Denmark", "gender": "Female", "latitude": "56.162939", "longitude": "10.203921" }, { "location": "Aarhus, Denmark", "gender": "Female", "latitude": "56.162939", "longitude": "10.203921" }......]};
<script src="http://gmaps-utility-library.googlecode.com/svn/trunk/markerclusterer/1.0/src/markerclusterer.js"></script>
<script src="http://gmaps-utility-library.googlecode.com/svn/trunk/markerclusterer/1.0/src/markerclusterer.js"></script>
var data = {"count": 232,"participants": [ { "location": "Aarhus, Denmark", "gender": "Female", "latitude": "56.162939", "longitude": "10.203921" }, { "location": "Aarhus, Denmark", "gender": "Female", "latitude": "56.162939", "longitude": "10.203921" }......]};
var markers = [];
for (var i = 0; i < data.participants.length; ++i) { var latlng = new GLatLng(data.participants[i].latitude, data.participants[i].longitude); var marker = new GMarker(latlng, {icon: icon}); markers.push(marker);}var markerCluster = new MarkerClusterer(map, markers);
var markers = [];
for (var i = 0; i < data.participants.length; ++i) { var latlng = new GLatLng(data.participants[i].latitude, data.participants[i].longitude); var marker = new GMarker(latlng, {icon: icon}); markers.push(marker);}var markerCluster = new MarkerClusterer(map, markers);
var layer = new google.maps.FusionTablesLayer(747060, { heatmap: true });
layer.setMap(map);
var layer = new google.maps.FusionTablesLayer(747060, { heatmap: true });
layer.setMap(map);
function plotCircles(map, dataPoints) {
...
for (var i = 0; i < dataPoints.length; i++) { pointLatLng = new google.maps.LatLng(dataPoints[i][1],dataPoints[i][2]); circleOptions = { strokeColor: "#FF0000", strokeOpacity: 0.8, strokeWeight: 2, fillColor: “#FF0000”, fillOpacity: 0.40, map: map, center: pointLatLng, radius: dataPoints[i][3]*3000 }; circle = new google.maps.Circle(circleOptions); }
function plotCircles(map, dataPoints) {
...
for (var i = 0; i < dataPoints.length; i++) { pointLatLng = new google.maps.LatLng(dataPoints[i][1],dataPoints[i][2]); circleOptions = { strokeColor: "#FF0000", strokeOpacity: 0.8, strokeWeight: 2, fillColor: “#FF0000”, fillOpacity: 0.40, map: map, center: pointLatLng, radius: dataPoints[i][3]*3000 }; circle = new google.maps.Circle(circleOptions); }
...
percentage = dataPoints[i][4];
if (percentage <= 10) { color = "#FF0000"; } else if (percentage >=20) { color = "#339900"; } else { color = "#FFCC00"; }
circleOptions = { strokeColor: color, ....
...
percentage = dataPoints[i][4];
if (percentage <= 10) { color = "#FF0000"; } else if (percentage >=20) { color = "#339900"; } else { color = "#FFCC00"; }
circleOptions = { strokeColor: color, ....
...
setMarkers (map, locations);infowindow = new google.maps.InfoWindow({ content: "loading..." });
....
...
setMarkers (map, locations);infowindow = new google.maps.InfoWindow({ content: "loading..." });
....
YAHOO! MAPS WEB SERVICES
.... icon = new YImage(); icon.src = "marker_34_red.png"; icon.size = new YSize(20,34); icon.offsetSmartWindow = new YCoordPoint(9,0);
....
var marker = new YMarker(point, icon);
....
.... icon = new YImage(); icon.src = "marker_34_red.png"; icon.size = new YSize(20,34); icon.offsetSmartWindow = new YCoordPoint(9,0); ....
var marker = new YMarker(point, icon);
....
GOOGLE CHARTS TOOLS
ConclusionsVisualize 2
sets of dataNo Coding Legend First Map Full Control
OpenHeatMap Easy
Google Fusion
TablesEasy
Google Charts Moderate
Socrata Moderate
Google Maps API Moderate
Yahoo Maps
Web ServicesModerate
Google Charts
ToolsModerate
Conclusions
Conclusions• Very easy to plot flat numbers with most tools
Conclusions• Very easy to plot flat numbers with most tools
• Plotting multiple sets of data without code is not trivial
Conclusions• Very easy to plot flat numbers with most tools
• Plotting multiple sets of data without code is not trivial
• Flash graphics still ahead of JS graphics with respect to data visualization
Conclusions• Very easy to plot flat numbers with most tools
• Plotting multiple sets of data without code is not trivial
• Flash graphics still ahead of JS graphics with respect to data visualization
• Most map and charting tools need better overall legend support
Conclusions• Very easy to plot flat numbers with most tools
• Plotting multiple sets of data without code is not trivial
• Flash graphics still ahead of JS graphics with respect to data visualization
• Most map and charting tools need better overall legend support
• Maps API products very similar in structure
Conclusions• Very easy to plot flat numbers with most tools
• Plotting multiple sets of data without code is not trivial
• Flash graphics still ahead of JS graphics with respect to data visualization
• Most map and charting tools need better overall legend support
• Maps API products very similar in structure
• We've uncovered just the tip of the iceberg in terms of data visualization
Conclusions• Very easy to plot flat numbers with most tools
• Plotting multiple sets of data without code is not trivial
• Flash graphics still ahead of JS graphics with respect to data visualization
• Most map and charting tools need better overall legend support
• Maps API products very similar in structure
• We've uncovered just the tip of the iceberg in terms of data visualization
• Our visualized data showed us that the more the people that attended the event, the more likely we were to meet the 20% challenge
Conclusions• Very easy to plot flat numbers with most tools
• Plotting multiple sets of data without code is not trivial
• Flash graphics still ahead of JS graphics with respect to data visualization
• Most map and charting tools need better overall legend support
• Maps API products very similar in structure
• We've uncovered just the tip of the iceberg in terms of data visualization
• Our visualized data showed us that the more the people that attended the event, the more likely we were to meet the 20% challenge
• We need to improve and automate our data collection process as much as possible
Conclusions• Very easy to plot flat numbers with most tools
• Plotting multiple sets of data without code is not trivial
• Flash graphics still ahead of JS graphics with respect to data visualization
• Most map and charting tools need better overall legend support
• Maps API products very similar in structure
• We've uncovered just the tip of the iceberg in terms of data visualization
• Our visualized data showed us that the more the people that attended the event, the more likely we were to meet the 20% challenge
• We need to improve and automate our data collection process as much as possible
• We need more women hackers
Conclusions• Very easy to plot flat numbers with most tools
• Plotting multiple sets of data without code is not trivial
• Flash graphics still ahead of JS graphics with respect to data visualization
• Most map and charting tools need better overall legend support
• Maps API products very similar in structure
• We've uncovered just the tip of the iceberg in terms of data visualization
• Our visualized data showed us that the more the people that attended the event, the more likely we were to meet the 20% challenge
• We need to improve and automate our data collection process as much as possible
• We need more women hackers
• When women do participate, they win!
RHoK #3 on June 4th and 5th
SIGN UP NOW!
Contact us
[email protected] [email protected]@avni321
Resources and further • http://msdn.microsoft.com/en-us/library/bb429619.aspx
• http://code.google.com/apis/chart/
• http://www.google.com/fusiontables/public/tour/index.html
• http://code.google.com/apis/maps/documentation/javascript/
• http://developer.yahoo.com/maps/
• http://www.openheatmap.com/
• http://googlegeodevelopers.blogspot.com/2009/04/markerclusterer-solution-to-too-many.html
• http://opendata.socrata.com/
Photo Credits• http://www.flickr.com/photos/compassalba/5361528668/sizes/o/in/photostream/
• http://www.flickr.com/photos/rhok_chicago/5244434726/in/set-72157625557470340
• http://www.flickr.com/photos/rhok_chicago/5233673064/in/set-72157625529538216
• http://www.flickr.com/photos/10785432@N03/4123252604/
• http://www.flickr.com/photos/thehbunny/5055948378/
• http://www.flickr.com/photos/53941041@N00/4977883190/
• http://www.flickr.com/photos/rhok_chicago/5243866521/
• http://www.flickr.com/photos/rhok_chicago/5244461658/in/set-72157625557470340
• http://www.flickr.com/photos/rhok_chicago/5233687260/in/set-72157625529538216
• http://www.flickr.com/photos/ladypain/1950149100/in/photostream/
• http://www.flickr.com/photos/10687935@N04/3055314845/
• http://www.flickr.com/photos/42788859@N00/318947873/