Revealing correlations with scatter charts

Scatter charts are great to show correlations between data. The following example will combine NASA/GISS global temperature data (Data/monthly_json.json) and CO2 emission data (Data/co2_mm_mlo.csv) measured in Mauna Loa, Hawaii, to discover if there is any correlation between the two. Since the Mauna Loa data is only available after 1959, we will only use the GISS data after that year.

Since we must load multiple files, we will use JavaScript promises. Each data source is parsed and the data is sent to the combine() function, which returns an array that can be used by Chart.js, as follows:

const canvas = document.getElementById("my-scatter-chart");
const files = ['../Data/monthly_json.json', '../Data/co2_mm_mlo.csv'];
var promises = files.map(file => fetch(file).then(resp => resp.text()));
Promise.all(promises).then(results => {
const temperatures = JSON.parse(results[0]);
const co2emissions = Papa.parse(results[1], {header: true}).data;
const data = combine(temperatures, co2emissions);
drawData(data);
});

The combine() function iterates through each object in the CO2 data, extracts the year and the month and uses it to obtain the corresponding mean temperature, then creates an object with the CO2 and temperature for each month/year. Each object is pushed into an array that is returned, as follows:

function combine(tempData, co2Data) {
const entries = [];
co2Data.filter(n => +n.year >= 1959).forEach(measure => {
const year = measure.year, month = measure.month;
let temperature = 0;
tempData.filter(n => n.Source=='GISTEMP' && +n.Date.split("-")
[0] >= 1959)
.forEach(temp => {
if(+temp.Date.split("-")[0] == year
&& +temp.Date.split("-")[1] == month) {
temperature = temp.Mean;
}
});
entries.push({ co2: measure.average, temp: temperature });
});
return entries;
}

The following drawData() function uses the array of objects that contains co2 and temp properties to draw the scatter chart by copying these values into {x,y} objects:

function drawData(datasets) {
const entries = [];
datasets.forEach(entry => {
const obj = { x: entry.co2, y: entry.temp };
entries.push(obj);
});
const dataObj = {
datasets: [
{
data: entries,
pointRadius: 2,
pointBackgroundColor: 'rgba(255,0,0,.5)'
}
]
}
const chartObj = {
type: "scatter",
data: dataObj,
options: { legend: { display: false } }
};
new Chart("my-scatter-chart", chartObj);
}

You can see the full code in ScatterBubble/scatter-4.html. The result is shown in the following chart and reveals a possible relationship between growing CO2 emissions and global temperatures. It also shows some data that we should have filtered out (if we had read the documentation that comes with the data), such as missing CO2 measurements, which appear as -99.99:

Comparing CO2 emissions (source: Mauna Loa) and global temperature (source: NASA; code: ScatterBubble/scatter-4.html)

We can filter out the bad measurements by adding an extra predicate to the co2Data filter, as follows:

co2Data.filter(n => +n.year >= 1959 && n.average > 0)

It's also a good idea to label the axes, so the viewer knows what kind of data is being compared. The following configuration adds axis titles and also a title for the chart. The full code is in ScatterBubble/scatter-5.html:

const chartObj = {
type: "scatter",
data: dataObj,
options: {
legend: { display: false},
title: {
display: true,
text: 'CO2 emissions vs. Global temperatures',
fontSize: 24
},
scales: {
xAxes: [{
scaleLabel: {
labelString: 'CO2 emissions (ppm)',
display: true
}
}],
yAxes: [{
scaleLabel: {
labelString: 'Temperature anomaly (Celsius)',
display: true
}
}],
}
}
};
new Chart("my-scatter-chart", chartObj);

 The final chart is shown as follows:

CO2 vs temperature scatter chart after filtering out wrong measurements (code: ScatterBubble/scatter-5.html)
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset