Published
Edited
Sep 12, 2022
Insert cell
# 1.First blood
Insert cell
md`# 全球温度变化趋势, 时间跨度:1880-2022, 包括拟合曲线


下面的图表显示了温度与1951-1980年平均值的偏差。


数据来源: [NASA Goddard Institute for Space Studies](https://data.giss.nasa.gov/gistemp/)`
Insert cell
md`## 制作意义
我们人类,地球上的生物,微生物都依赖气候资源活着。我们之所以有生物多样性,有比较稳定的生态系统,就是因为气候是一个长时间尺度下比较稳定的要素。比如北极熊稳定地在北极附近繁衍生息,热带雨林稳定的为地球维持大气稳定。热带浅海区域的珊瑚生态系统也能长期稳定存在。但是我们的温室气体排放已经越来越快的打破这些平衡。这种平衡一旦失衡到一定程度就会不可逆。



中国作为北半球最大的国家,拥有丰富的气候,全球气候的变化与我们每一个中国人息息相关。在此次实验中,通可视化能让我们看出北半球近几十年的变化,帮助我们分析气候的变化,以采取措施`
Insert cell
下面是所有数据和交互界面,我们可以通过控制bandwidth来控制拟合曲线实现交互效果
Insert cell
Inputs.table(data)//查看所有数据
Insert cell
viewof bandwidth = Inputs.range([0, 1], {
value: .15,
label: "bandwidth",
step: .01
});
Insert cell
{
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

svg.append("g")
.call(xAxis);

svg.append("g")
.call(yAxis);

svg.append("g")
.attr("stroke", "green")
.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", d => x(d.date))
.attr("cy", d => y(d.value))
.attr("fill", d => z(d.value))
.attr("r", 3);
svg.append("path")
.datum(regression(data))
.style("fill", "none")
.style("stroke", "red")
.attr("d", line);

return svg.node();
}
Insert cell
md`### 来源和数据`
Insert cell
md`### 布局`
Insert cell
height = 800
Insert cell
margin = ({top: 6, right: 6, bottom: 30, left: 50})
Insert cell
md`### Data`
Insert cell
north1 = FileAttachment("NORTH@1.csv").csv()
Insert cell
data = {
const data = [];
// https://data.giss.nasa.gov/gistemp/tabledata_v3/GLB.Ts+dSST.csv
await d3.csvParse(await FileAttachment("NORTH@1.csv").text(), (d, i, columns) => {
for (let i = 1; i < 13; ++i) {
const value = +d[columns[i]];
if (value){
data.push({
date: new Date(d.Year, i - 1, 1),
value
});
}
}
});
return data;
}
Insert cell
md`### 图形 & 功能`
Insert cell
regression = d3.regressionLoess()
.x(d => d.date)
.y(d => d.value)
.bandwidth(bandwidth);
Insert cell
line = d3.line()
.x(d => x(d[0]))
.y(d => y(d[1]));
Insert cell
x = d3.scaleTime()
.domain(d3.extent(data, d => d.date))
.range([margin.left, width - margin.right])
Insert cell
y = d3.scaleLinear()
.domain(d3.extent(data, d => d.value)).nice()
.range([height - margin.bottom, margin.top])
Insert cell
z = {
const max = d3.max(data, d => Math.abs(d.value));
return d3.scaleSequential(d3.interpolateRdBu).domain([max, -max]);
}
Insert cell
xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).ticks(width / 80).tickSizeOuter(0))
Insert cell
yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y).ticks(null, "+"))
.call(g => g.select(".domain").remove())
.call(g => g.selectAll(".tick line")
.filter(d => d === 0)
.clone()
.attr("x2", width - margin.right - margin.left)
.attr("stroke", "#ccc"))
.call(g => g.append("text")
.attr("fill", "#000")
.attr("x", 5)
.attr("y", margin.top)
.attr("dy", "0.32em")
.attr("text-anchor", "start")
.attr("font-weight", "bold")
.text("Anomaly (°C)"))
Insert cell
d3 = require("d3@7", "d3-regression@1")
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more