演示视频:数据可视化大作业_HIV可视化分析_哔哩哔哩_bilibili
PPT汇报:数据可视化大作业 (HIV数据研究及可视化 javascript d3 +python 爬虫 + 页面整合)_阿阿阿扶的博客-CSDN博客_数据可视化大作业
参考代码来源:Codepen
演示GIF:
1.数据的读入和字段含义:
读取文件,共两个文件—geo地理位置json文件和各国HIV感染现状csv文件;使用d3.v4.js,读取代码如下:
d3.queue()
.defer(d3.json, "./content1/50m.json")
.defer(d3.csv, "./content1/m7.csv", row => {
return {
continent: row.Continent,
country:row.Country,
countryCode: row["Code"],
DeathRate: +row["HIV_AIDS_ALL_Deaths"],
InfectionRate: +row["Prevalence"],
region: row.Region,
year: +row.Year,
inc:+row["inc"]
}
})
m7.csv表格中共包含5700条数据,数据来源于http://ghdx.healthdata.org/gbd-results
-tool,下载的单个原数据集只包含一个艾滋相关的字段值,将地域信息和年份进行匹配之后,得到如下的表格,表格预览和字段解释如下:
图8 m7.csv表格数据
若想获取使用的数据集,点击下载数据即可。
图9 点击按钮
D3分别将表中的国家信息,和地理编码读入,根据countryCode字段值在50m.json匹配地理的位置;将每年艾滋死亡率占比总死亡率、人口感染率、新增艾滋感染患者字段的值分别存入 DeathRate,InfectionRate和inc,用于渲染视图;国家的对应的信息(大洲)也读入continent,用于按洲信息绘制饼图。年份信息用于更新各个视图。
2.地图的可视化和信息更新:
地图有两种模式,分别是DeathRate和InfectionRate。HTML中代码如下所示,默认为DeathRate模型的地图可视,根据单选框Radio实现地图模式的切换:
图10 两种地图模式
HTML代码实现如下:
<input type="radio" name="data-type" value="DeathRate" checked>
<label>艾滋死亡占总死亡比率</label>
<input type="radio" name="data-type" value="InfectionRate">
<label>人口感染艾滋比例</label>
在js中,根据data-type的value进行相应更换,更换的代码如下:
var currentDataType = d3.select('input[name="data-type"]:checked') //读取data-type类型
.attr("value");
..........
d3.selectAll('input[name="data-type"]') //根据data-type切换数据
.on("change", () => {
var active = d3.select(".active").data()[0];
drawPie(data, currentYear, currentDataType);
drawMap(geoData, data, currentYear, currentDataType);
});
我们还添加了时间进度条,根据不同年份数据渲染地图、饼图;拖动进度条,查看不同年份数据详情。
图 11时间进度条选择
在HTML中增添类型为range的时间条,年份间隔为1:
<p>
年份选择: <span id="year-val"></span>
<input id="year" type="range" step="1">
</p>
在js中,根据年份信息匹配数据:
d3.select("#year")
.property("min", currentYear)
.property("max", extremeYears[1])
.property("value", currentYear) //获得当前年份信息
.on("input", () => {
currentYear = +d3.event.target.value; //根据年份绘制地图,饼图
drawMap(geoData, data, currentYear, currentDataType);
});
画地图函数为drawMap(geoData, HIVData, year, dataType),geoData即我们的地理数据,HIVData为艾滋病相关数据。根据年份和选择模式进行地图的渲染,效果为下:
图 12地图渲染
地图的titile更换如下,需要根据数据类型和当前的年份做调整;
d3.select(".map-title")
.text("" +(dataType === "DeathRate" ? "Share of deaths from HIV/AIDS" : "Share of the population infected with HIV")+graphTitle(dataType) +","+ year);
Tooltip的应用,用于在视图上更好的交互信息:
d3.selectAll("#map")
.on("mousemove touchmove", updateTooltip);
d3.selectAll("#pie")
.on("mousemove touchmove", updateTooltip);
d3.selectAll("#bar")
.on("mousemove touchmove", updateTooltip);
主要把国家的信息,要展示的HIV数据情况和年份信息并进行交互。其中地图、柱形图和其中一个饼图的tooltip是一样的,因为展现New case饼图只根据每年每国的新增病例来提供交互信息。
地图国家的颜色根据对应艾滋数据更改,颜色偏红黑调:
//地图颜色的更改
var colors=["#FFEFD5","#f1c40f","#FFB90F","#FF4500","#800000"];
var domains = {
DeathRate: [0,0.03, 0.5, 1.0, 6,20],
InfectionRate: [0,0.03, 0.5,1.0,5,10]
};
3.地图和柱状图之间的联动:
选中地图中的国家,可以就将该国家的近30年来的艾滋数据显示在右侧的柱形图中,用于研究各国近期艾滋的详情和对应的趋势变化,从而达到数据可视和数据分析的效果。如下图所示:
图13 交互地图和图表联动
例如,在地图中点击选中Russia,右图中将Russia这个国家近30年对应地图模式的信息使用条形图展现出来,同时根据时间进度条的年份高亮对应的年份的条形。
条形图绑定国家信息:一开始先绘制好所有的图表,在我们未在地图中选中国家时,条形图不展示任何信息,只有坐标轴在视图中。根据d3.select(".active").data()[0]来获取我们选中的国家的名称,根据国家名称来绘制条形图,同时条形图也有逐渐弹升和逐渐消失的效果,更加美观,给用户更多反应的时间。JS中的代码实现如下:
d3.selectAll('input[name="data-type"]')
.on("change", () => {
var active = d3.select(".active").data()[0];
var country = active ? active.properties.country : ""; //绑定选中国家名称
currentDataType = d3.event.target.value;
drawMap(geoData, data, currentYear, currentDataType);
drawBar(data, currentDataType, country); //绘制对应国家30年具体数据条形图
});
在地图绘制函数中添加对应的更新函数,使在地图上先选中该国家后,右边条形图随着动画效果绘制近三十年的艾滋数据情况,再次选中该国家,则条形图消失:
update
.enter()
.append("path")
.classed("country", true)
.attr("d", path)
.on("click", function() {
var currentDataType = d3.select("input:checked")
.property("value");
var country = d3.select(this);
var isActive = country.classed("active");
var countryName = isActive ? "" : country.data()[0].properties.country;
drawBar(climateData, currentDataType, countryName);//绘制对应国家30年具体数据条形图
highlightBars(+d3.select("#year").property("value"));//高亮
d3.selectAll(".country").classed("active", false); //再次选中该国家则条形图消失
country.classed("active", !isActive);
})
.merge(update)
.transition()
.duration(750) //条形图的过渡效果
.attr("fill", d => {
var val = d.properties[dataType];
return val ? mapColorScale(val) : "#ccc"; });
根据鼠标选中的国家信息和模式信息,作为参数传入drawBar函数中,绘制该国家的近30年艾滋数据详情。
高亮条形:根据拖动的当前年份信息,传入highlightBars函数,高亮这条条形,将选中额年份的条形颜色加深,使得研究者更加方便地查看信息:
d3.select("#year")
.property("min", currentYear)
.property("max", extremeYears[1])
.property("value", currentYear)
.on("input", () => {
currentYear = +d3.event.target.value;
drawMap(geoData, data, currentYear, currentDataType);
highlightBars(currentYear); //高亮选中年份对应条形图
});
4.按各国家地域信息(洲)展示饼图:
将处于一个洲的国家绘制通一个颜色,并且聚集在一处。饼图显示当前年份国家艾滋数据占全球数据的占比构成,根据当前年份和模式会进行更新变化。因为在读入数据时,已经把国家的地域信息(洲)存在continent字段中,根据地域信息和数据详情使得国家排序:
var pie = d3.select("#pie");
var arcs = d3.pie()
.sort((a,b) => {
if (a.continent < b.continent) return -1;
if (a.continent > b.continent) return 1;
return a[dataType] - b[dataType];})
.value(d => d[dataType]);
js中根据洲信息来使得位于同一个洲的国家在饼图中表现为一个颜色,代码如下所示:
var colorScale = d3.scaleOrdinal()
.domain(continents)
.range(["#26a69a", "#87CEEB","#42a5f5", "#4682B4","#3CB371",
"#ab47bc", "#7e57c2"]);
........
update
......
.merge(update)
.attr("fill", d => colorScale(d.data.continent))
.attr("d", path);
以此,可以允许研究者以洲的角度为切入,观察各个国家新增病例随着时间改变在全球的占比情况及死亡率,感染率占比情况等,也可以探索邻近国家的感染原因的关系等。饼图的可视化结果如下:
图14各国每年新增艾滋病例饼图