? ?
写在前面
本文针对爬取的全国大学信息,使用Echarts进行可视化呈现。包括经典的折线图、柱状图、饼图,以及更加有趣的玫瑰图、矩形树图、极坐标图、分布地图等。
另外,原始数据(json),完整代码(html)均已上传,文末可见。
? ?
Stacked Area Chart(堆叠面积图)
Description:一所大学的总分(score)是多个维度得分的总和,比如办学层次、学科水平、办学资源、师资规模、重大成果、国际竞争等。堆叠面积图直观展现了某所院校的总分情况及其得分组成,并且还可以进行总分或者某维度得分的横向对比。
Example:下图展现了我国C9院校(2028)的得分及其得分组成情况,可以得到诸如以下结论:清北院校的得分显著高于哈工大;在所有院校中人才培养得分均占比较高;各院校国际竞争力得分相似,但在重大项目与成果方面随排名呈递减趋势。
Code:
const C9 = ["清华大学", "北京大学", "浙江大学", "上海交通大学", "南京大学", "复旦大学", "中国科学技术大学", "西安交通大学", "哈尔滨工业大学"];
const ST = ["办学层次", "学科水平", "办学资源", "师资规模与结构", "人才培养", "科学研究", "服务社会", "学术人才", "重大项目与成果", "国际竞争力"];
var data = [];
for (var i = 0; i < raw.length; i++) {
if (C9.includes(raw[i]["学校名称"])) {
data.push(raw[i]);
}
}
var scores = [];
for (var i = 0; i < ST.length; i++) {
var score = [];
for (var j = 0; j < data.length; j++) {
score.push(data[j][ST[i]]);
}
scores.push(score);
}
var series = [];
for (var i = 0; i < 10; i++) {
series.push({
name: ST[i],
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: scores[i]
});
}
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
top: '5%',
data: ST
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: C9
}
],
yAxis: [
{
type: 'value'
}
],
series: series
};
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);
? ?
Stacked Horizontal Chart(堆叠条形图)
Description:和上面的堆叠面积图类似,不仅展现了总分的对比,还可以进行总分各组成成分的横向对比。
Example:下图同样展现了我国C9院校(2028)的得分及其得分组成情况,结论同上方堆叠面积图。
Code:
const C9 = ["清华大学", "北京大学", "浙江大学", "上海交通大学", "南京大学", "复旦大学", "中国科学技术大学", "西安交通大学", "哈尔滨工业大学"];
const ST = ["办学层次", "学科水平", "办学资源", "师资规模与结构", "人才培养", "科学研究", "服务社会", "学术人才", "重大项目与成果", "国际竞争力"];
var data = [];
for (var i = 0; i < raw.length; i++) {
if (C9.includes(raw[i]["学校名称"])) {
data.push(raw[i]);
}
}
var scores = [];
for (var i = 0; i < ST.length; i++) {
var score = [];
for (var j = 0; j < data.length; j++) {
score.push(data[j][ST[i]]);
}
scores.push(score.reverse());
}
var series = [];
for (var i = 0; i < 10; i++) {
series.push({
name: ST[i],
type: 'bar',
stack: 'total',
label: {
show: true
},
emphasis: {
focus: 'series'
},
data: scores[i]
});
}
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
top: '3%'
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'value'
},
yAxis: {
type: 'category',
data: C9.reverse()
},
series: series
};
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);
? ?
Chinese Distribution Map(中国分布地图)
Description:以省份为单位,统计了我国大学的分布情况。光标悬浮时即可显示该省大学数量。另外,为了更直观展现我国大学的地区分布规律,地图用红色(#8debff)和蓝色(#ff8dab)进行着色。颜色越红,该省大学数量越多;颜色越蓝,该省大学数量越少;灰色表示暂无数据信息。
Example:从局部来看,江苏拥有最高的大学数量(37所),青海、西藏、宁夏拥有最少的大学数量(仅1所);从整体来看,我国大学分布呈现“西部少,东部多,不平衡”的特征,这其实与客观地理位置、教育资源投资、经济发展水平等因素息息相关。
Code:
var locate = {};
for (var i = 0; i < raw.length; i++) {
if (raw[i]["省市"] in locate) {
locate[raw[i]["省市"]] += 1;
} else {
locate[raw[i]["省市"]] = 0;
}
}
var data = [];
for (var province in locate) {
data.push({
name: province,
value: locate[province]
});
}
option = {
tooltip: {
formatter: function (params, ticket, callback) {
return params.seriesName + '<br />' + params.name + ':' + params.value
}
},
visualMap: {
min: 1,
max: 40,
left: 'left',
top: 'bottom',
text: ['多', '少'],
inRange: {
color: ['#8debff', '#ff8dab']
},
show: true
},
geo: {
map: 'china',
roam: false,
zoom: 1.23,
label: {
normal: {
show: true,
fontSize: '10',
color: 'rgba(0,0,0,0.7)'
}
},
itemStyle: {
normal: {
borderColor: 'rgba(0, 0, 0, 0.2)'
},
emphasis: {
areaColor: '#F3B329',
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 20,
borderWidth: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
},
series: [
{
name: '省内大学数量',
type: 'map',
geoIndex: 0,
data: data
}
]
};
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);
? ?
Basic Bar Chart(基础柱状图)
Description:统计了各省份的大学数量,并直观的通过柱状图的高度展现出来。光标悬浮时,可显示所选省份的具体大学数量。
Example:从以下柱状图中我们可以直观的看到,江苏、山东、河南三省的高校数量最多,宁夏、青海、西藏三省的高校数量最少。
Code:
var map = {};
for (var i = 0; i < raw.length; i++) {
if (raw[i]["省市"] in map) {
map[raw[i]["省市"]] += 1;
} else {
map[raw[i]["省市"]] = 0;
}
}
var list = [];
for (var province in map) {
list.push({
province: province,
count: map[province]
});
}
list.sort(function (obj1, obj2) {
if (obj1.count < obj2.count) {
return 1;
} else if (obj1.count > obj2.count) {
return -1;
} else {
return 0;
}
});
var provinces = [];
var statistic = [];
for (var i = 0; i < list.length; i++) {
if (i > 14 && i < 19) {
continue;
}
provinces.push(list[i].province);
statistic.push(list[i].count);
}
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: provinces,
axisTick: {
alignWithLabel: true
}
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: 'Direct',
type: 'bar',
barWidth: '60%',
data: statistic
}
]
};
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);
? ?
Positive and Negative Column Chart(正负柱状图)
Description:统计了各大学的排名波动情况。光标悬浮时,可显示所选大学的具体排名波动数。
Example:从下图中可以直观看出,排名靠前的大学排名波动并不大,排名位于中档的大学排名波动较大,排名靠后的大学整体呈现排名下滑的态势。
Code:
var univ = [];
var data = [];
for (var i = 0; i < raw.length; i++) {
univ.push(raw[i]['学校名称']);
data.push(raw[i]['升/降']);
}
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
formatter: function (params) {
var wave = params[0].data;
var index = params[0].dataIndex;
return "学校名称: " + univ[index] + "</br>排名波动: " + wave;
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
show: false,
type: 'category',
axisTick: {
alignWithLabel: true
}
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
type: 'bar',
showBackground: true,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#83bff6' },
{ offset: 0.5, color: '#188df0' },
{ offset: 1, color: '#188df0' }
])
},
emphasis: {
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#2378f7' },
{ offset: 0.7, color: '#2378f7' },
{ offset: 1, color: '#83bff6' }
])
}
},
data: data
}
]
};
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);
? ?
Bar Chart on Polar(极坐标柱状图)
Description:极坐标柱状图以省份为单位,统计了每个省份的大学最高得分、最低得分、得分平均分,并将其展现在极坐标域中(不是数学定义中的极坐标)。两侧的蓝色部分展示了最低得分和最高得分,中间的绿色部分展示了平均得分。另外,图表根据平均分进行了排序。
Example:从下图中可以直观看出,北京拥有最高平均得分,上海、江苏紧随其后;贵州、山西等地平均得分最低;浙江虽然平均得分不在前列,但拥有很高的最高得分;从整体上看,最高得分和平均得分基本呈正相关。
Code:
var locate = {};
for (var i = 0; i < raw.length; i++) {
if (!(raw[i]["省市"] in locate)) {
var info = {};
info["scores"] = [];
info["max"] = 0;
info["min"] = 0;
info["ave"] = 0;
locate[raw[i]["省市"]] = info;
}
locate[raw[i]["省市"]]["scores"].push(parseFloat(raw[i]["总分"]));
}
for (var province in locate) {
var scores = locate[province].scores;
var cnt = 0;
var sum = 0;
var max = Number.MIN_VALUE;
var min = Number.MAX_VALUE;
for (var i = 0; i < scores.length; i++) {
if (scores[i]) {
sum += scores[i];
cnt += 1;
max = Math.max(max, scores[i]);
min = Math.min(min, scores[i]);
}
}
locate[province].max = max;
locate[province].min = min;
locate[province].ave = sum / cnt;
}
var list = []
for (var province in locate) {
var obj = {};
obj["province"] = province;
obj["max"] = locate[province].max;
obj["min"] = locate[province].min;
obj["ave"] = locate[province].ave;
list.push(obj);
}
for (var i = 0; i < list.length; i++) {
list[i].ave = list[i].ave.toFixed(1);
}
list.sort(function (obj1, obj2) {
if (obj1.ave < obj2.ave) {
return 1;
} else if (obj1.ave > obj2.ave) {
return -1;
} else {
return 0;
}
});
var provinces = [];
var statistic = [];
for (var i = 0; i < list.length; i++) {
if (i > 15 && i < 18) {
continue;
}
provinces.push(list[i].province);
statistic.push([list[i].min, list[i].max, list[i].ave]);
}
const data = statistic;
const cities = provinces;
const barHeight = 50;
option = {
legend: {
show: true,
top: 'bottom',
data: ['Range', 'Average']
},
grid: {
top: 100
},
angleAxis: {
type: 'category',
data: cities
},
tooltip: {
show: true,
formatter: function (params) {
const id = params.dataIndex;
return (
cities[id] +
'<br>Lowest:' +
data[id][0] +
'<br>Highest:' +
data[id][1] +
'<br>Average:' +
data[id][2]
);
}
},
radiusAxis: {},
polar: {},
series: [
{
type: 'bar',
itemStyle: {
color: 'transparent'
},
data: data.map(function (d) {
return d[0];
}),
coordinateSystem: 'polar',
stack: 'Min Max',
silent: true
},
{
type: 'bar',
data: data.map(function (d) {
return d[1] - d[0];
}),
coordinateSystem: 'polar',
name: 'Range',
stack: 'Min Max'
},
{
type: 'bar',
itemStyle: {
color: 'transparent'
},
data: data.map(function (d) {
return d[2] - barHeight;
}),
coordinateSystem: 'polar',
stack: 'Average',
silent: true,
z: 10
},
{
type: 'bar',
data: data.map(function (d) {
return barHeight * 2;
}),
coordinateSystem: 'polar',
name: 'Average',
stack: 'Average',
barGap: '-100%',
z: 10
}
]
};
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);
? ?
Basic Pie Chart(基础饼图)
Description:饼图可以直观展现各组成成分的占比情况,非常简单的图表。
Example:从下面的图表可以看出,我国院校以综合、理工、师范三种类型为主,农业、林业、以及其他类型院校占比较少。
Code:
const types = ['综合', '理工', '师范', '农业', '林业'];
const other = '其他';
var map = {};
for (var i = 0; i < types.length; i++) {
map[types[i]] = 0;
}
map[other] = 0;
for (var i = 0; i < raw.length; i++) {
if (types.includes(raw[i]["类型"])) {
map[raw[i]["类型"]] += 1;
} else {
map[other] += 1;
}
}
var data = [];
for (var key in map) {
data.push({
name: key,
value: map[key]
});
}
option = {
tooltip: {
trigger: 'item'
},
legend: {
top: '5%',
left: 'center'
},
series: [
{
name: '院校类型',
type: 'pie',
radius: '65%',
data: data,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);
? ?
Doughnut Chart(环形图)
Description:环形图可以直观展现各组成成分的占比情况,非常简单的图表。
Example:从下面的图表可以看出,我国院校以综合、理工、师范三种类型为主,农业、林业、以及其他类型院校占比较少。
Code:
const types = ['综合', '理工', '师范', '农业', '林业'];
const other = '其他';
var map = {};
for (var i = 0; i < types.length; i++) {
map[types[i]] = 0;
}
map[other] = 0;
for (var i = 0; i < raw.length; i++) {
if (types.includes(raw[i]["类型"])) {
map[raw[i]["类型"]] += 1;
} else {
map[other] += 1;
}
}
var data = [];
for (var key in map) {
data.push({
name: key,
value: map[key]
});
}
option = {
tooltip: {
trigger: 'item'
},
legend: {
top: '5%',
left: 'center'
},
series: [
{
name: '院校类型',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '40',
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: data
}
]
};
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);
? ?
Nightingale Chart(南丁格尔玫瑰图)
Description:弗罗伦斯·南丁格尔或许是位为人所熟知的护士,但大多数不曾知道她还是一位统计学家。这种圆形的直方图被称为“南丁格尔的玫瑰”,这种图案曾被这位伟大的护士用于表达军医院季节性的死亡率,使得医事改良提案获得了女王的支持。南丁格尔玫瑰图用于表达新冠疫情各国死亡数时,效果十分震撼人心。
Example:从下面的图表可以看出,我国院校以综合、理工、师范三种类型为主,农业、林业、以及其他类型院校占比较少。
Code:
const types = ['综合', '理工', '师范', '农业', '林业'];
const other = '其他';
var map = {};
for (var i = 0; i < types.length; i++) {
map[types[i]] = 0;
}
map[other] = 0;
for (var i = 0; i < raw.length; i++) {
if (types.includes(raw[i]["类型"])) {
map[raw[i]["类型"]] += 1;
} else {
map[other] += 1;
}
}
var data = [];
for (var key in map) {
data.push({
name: key,
value: map[key]
});
}
option = {
legend: {
top: '5%',
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
series: [
{
name: '院校类型',
type: 'pie',
radius: [100, 260],
center: ['50%', '45%'],
roseType: 'radius',
itemStyle: {
borderRadius: 8
},
label: {
show: false
},
emphasis: {
label: {
show: true
}
},
data: data
}
]
};
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);
? ?
Tree Map(矩形树图)
Description:矩形树图把具有层次关系的数据可视化为一组嵌套的矩形,它直观地以面积表示数值,以颜色表示类目。所有矩形的面积之和表示整体的大小,各个小矩形的面积表示每个子项的占比,矩形面积越大,表示子数据在整体中的占比越大。矩形树图擅长可视化带权重的数据关系。
Example:根据得分(score)将大学分为了九个档次(A+、A、A-、B+、B、B-、C+、C、C-)。每个色块表示一个档次,色块的大小与该档次院校个数成正比。每个色块都是可点击进入的,进入的下一层为属于该档次的所有院校,在这一层中,色块的大小与该院校得分成正比。
Code:
const len = 9;
const standard_nam = ['A+', 'A', 'A-', 'B+', 'B', 'B-', 'B+', 'B', 'B-'];
const standard_num = [700, 400, 225, 200, 175, 150, 125, 100, 0];
var data = [];
for (var i = 0; i < len; i++) {
data.push({
type: "root",
name: standard_nam[i],
value: 0,
children: []
});
}
var index = 0;
for (var i = 0; i < raw.length; i++) {
if (raw[i]['总分'] >= standard_num[index]) {
data[index].value += 1;
data[index].children.push({
type: "leaf",
name: raw[i]['学校名称'],
value: raw[i]['总分']
});
} else {
index++;
}
}
option = {
tooltip: {
formatter: function (params) {
if (params.data.type == "root") {
var level = params.data.name;
var amount = params.data.value;
var minBorder, maxBorder;
if (level == 'A+') {
minBorder = 700;
maxBorder = 1000;
} else {
minBorder = standard_num[standard_nam.indexOf(level)];
maxBorder = standard_num[standard_nam.indexOf(level) - 1]
}
return "学校评级: " + level + "</br>高校数量: " + amount + "</br>分数区间: [" + minBorder + ", " + maxBorder + ")";
} else {
var university = params.data.name;
var score = params.data.value;
return "学校名称: " + university + "</br>学校得分: " + score;
}
}
},
series: [
{
name: 'option',
type: 'treemap',
visibleMin: 300,
data: data,
leafDepth: 1,
roam: false,
levels: [
{
itemStyle: {
borderColor: '#555',
borderWidth: 4,
gapWidth: 4
}
},
{
colorSaturation: [0.3, 0.6],
itemStyle: {
borderColorSaturation: 0.7,
gapWidth: 2,
borderWidth: 2
}
},
{
colorSaturation: [0.3, 0.5],
itemStyle: {
borderColorSaturation: 0.6,
gapWidth: 1
}
},
{
colorSaturation: [0.3, 0.5]
}
]
}
]
}
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);
? ? ? ?
写在后面
一些有用的资源:
- 原始数据(.csv)
- 原始数据(.json)
- 完整项目(.html)
一些有用的网址:
- Echarts(戳这里)
- CSDN(戳这里)
- Github(戳这里)
|