CS 725/825 - Spring 2018 - Homework 3 - Scatterplot
Hussam Hallak
1. What is the type of mark used in the scatterplot?
2. List the channels, the attribute they are mapped to, and the data type of that attribute.
Answer
The type of marks used in the scatter plot is a point. The channels are the horizontal and vertical spacial positions which encode quantitative attributes which are the number of passing touchdowns (TDs) and the number of rushing TDs for each player. The data type for both TDs is attribute. Each point represents a player, an item or an entity.
Edit the chart to use the color hue channel to express the "Conf" attribute (there are 11 conferences) and use the size channel to express another attribute in the dataset.
Similar to what I have done for the bar charts, I added this line of code:
var color = d3.scaleOrdinal(d3.schemeCategory20);
I also added this line in the section of the code //draw dots
which gives colors to the dots based on the "Conf" value
.style("fill", function(d) { return color(d.Conf)})
I also added the size channel to the mix by adding this line of code under the //draw dots
section, which changes the radius of the dot or point based on a value that combines values from two different columns in the data file:
.attr("r", function(d) { return d.Pct * d.Rate * 0.0005})
I have absolutely no idea what Pct and Rate are, but I tried with a couple of different attributes like Attempts and others. They all do not seem to make the difference in points' sizes obvious enough. I tried using the logScale on them, but that did not help so I commented its code. I finally tried multiplying the Rate and Pct and multiplying that by 0.0005 and that gave the best possible result. This is the section of the code //draw dots
:
// draw dots
g.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", function(d) { return d.Pct * d.Rate * 0.0005})
.attr("cx", xMap)
.attr("cy", yMap)
.style("fill", function(d) { return color(d.Conf)})
3. After your changes, list the channels, the attribute they are mapped to, and the data type of that attribute.
Answer
The channels are the horizontal and vertical spacial positions which encode quantitative attributes which are the number of passing touchdowns (TDs) and the number of rushing TDs for each player. The data type for both TDs is attribute. Each point represents a player, an item or an entity. Another channel is the color hue which is an identity channel that encodes the conference which is a categorical attribute, which is an item as far as data type. Another channel is size which encodes Pct * Rate * k where k = 0.0005 and this attribute is quantitative and its data type is attribute. In this case, the value is new quatitative attribute that is constructed from the two existing quatitative attributes Pct and Rate.
xxxxxxxxxx
<html>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> <!-- for color scales -->
<!-- Example based on https://bl.ocks.org/mbostock/3887118 -->
<!-- Tooltip example from https://www.d3noob.org/2013/01/adding-tooltips-to-d3js-graph.html -->
<style>
body { font-family: calibri; }
.axis { font: 14px calibri; }
.label {font: 16px calibri; }
.tooltip {
position: absolute;
width: 150px;
height: 60px;
background: #f2f2f2;
pointer-events: none;
}
</style>
<body>
<h2>Scatterplot</h2>
<div><svg id="chart1" width="700" height="400"></svg></div>
<script>
// add the graph canvas to the body of the webpage
var svg = d3.select("#chart1"),
margin = {top: 20, right: 20, bottom: 50, left: 70},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var color = d3.scaleOrdinal(d3.schemeCategory20);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// add the tooltip area to the webpage
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// load data
d3.csv("passing-stats-2014.csv", function (d) {
// change string (from CSV) into number format
d["Passing TD"] = +d["Passing TD"];
d["Rushing TD"] = +d["Rushing TD"];
return d;
}, function(error, data) {
if (error) throw error;
/*
* value accessor - returns the value to encode for a given data object.
* scale - maps value to a visual display encoding, such as a pixel position.
* map function - maps from data value to display value
*/
// setup x
var xValue = function(d) { return d["Rushing TD"];}, // data -> value
xScale = d3.scaleLinear().range([0, width]), // value -> display
xMap = function(d) { return xScale(xValue(d));}; // data -> display
// setup y
var yValue = function(d) { return d["Passing TD"];}, // data -> value
yScale = d3.scaleLinear().range([height, 0]), // value -> display
yMap = function(d) { return yScale(yValue(d));}; // data -> display
// don't want dots overlapping axis, so add in buffer to data domain
xScale.domain([d3.min(data, xValue)-1, d3.max(data, xValue)+1]);
yScale.domain([0, d3.max(data, yValue)+1]);
// x-axis
g.append("g")
.attr("class", "axis x-axis")
.attr("transform", "translate(0," + height + ")") // move axis to bottom of chart
.call(d3.axisBottom(xScale));
// x-axis label
g.append("text")
.attr("class", "label")
.attr("x", width/2)
.attr("y", height+(margin.bottom*0.75))
.style("text-anchor", "middle")
.text("Rushing TDs");
// y-axis
g.append("g")
.attr("class", "axis y-axis")
.call(d3.axisLeft(yScale));
// y-axis label
g.append("text")
.attr("class", "label")
.attr("x", 0-(height/2))
.attr("y", 0-(margin.left*0.55))
.attr("transform", "rotate(-90)") // rotate text -90 degrees from x, y
.style("text-anchor", "middle")
.text("Passing TDs");
//var dataVals = data.map(function(e) {return e.Attempts});
//var minVal = d3.min(dataVals);
//var maxVal = d3.max(dataVals);
//var multiplier = 11/(maxVal-minVal);
//var logScale = d3.scaleLog()
//.domain([20, 2000])
//.range([0, 10]);
// draw dots
g.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", function(d) { return d.Pct * d.Rate * 0.0005})
.attr("cx", xMap)
.attr("cy", yMap)
.style("fill", function(d) { return color(d.Conf)})
// tooltip
.on("mouseover", function(d) {
tooltip.transition()
.duration(200) // ms delay before appearing
.style("opacity", .8); // tooltip appears on mouseover
tooltip.html(d["Player"] + "<br/> " + d.School + "<br/>(" + xValue(d)
+ ", " + yValue(d) + ")")
.style("left", (d3.event.pageX + 10) + "px") // specify x location
.style("top", (d3.event.pageY - 28) + "px"); // specify y location
})
.on("mouseout", function(d) {
tooltip.transition()
.duration(500)
.style("opacity", 0); // disappear on mouseout
});
});
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js
https://d3js.org/d3-scale-chromatic.v1.min.js