“数”说亚运会!带你盘点亚运会背后的故事

10月8日,第19届杭州亚运会在数字人的比心中顺利闭幕了。在过去的十几天中,亚洲各国的运动健儿顽强拼搏,赛出了友谊,也赛出了风采。

为了更好的了解参加亚运会的运动员,我们收集所有参赛选手的信息,包含姓名、国籍、年龄和获得金牌数等,然后用 G2 对其进行了简单的可视化探索。

那么接下来我们就来了解整个流程和最后的可视化结果吧!完整的可视化分析页面和代码在这里

数据收集

首先是数据的收集。我们收集的运动员数据来自于亚运会官网,该数据是一份如下的表格数据:

每一列对应一位运动员,一共有11808位运动员的信息,这里简单介绍一下每个字段的含义:

  • birthday:运动员的生日
  • gender:运动员的性别
  • age:运动员的年龄
  • height:运动员的身高,单位为米
  • name:运动员的姓名
  • sport:参加的运动项目名字
  • sold:该运动员获得的金牌数
  • silver:该运动员获得的银牌数
  • bronze:该运动员获得的铜牌数
  • code:运动员的唯一 id
  • noc:国家的缩写
  • org:国家的编号
  • dis:参加的运动项目名字的缩写
  • img_id:图片的 id

如果想了解更多数据的信息、获取方法或者下载数据,可以访问这个 github 仓库。

选择可视化工具

在获得了数据之后,就需要选择我们的可视化工具了:这里我们选择了 AntV 的 G2

选择 G2 的原因是在其 5.0 版本中提供了 transform API ,内置了一系列数据探索的方法,可以方便地对原始数据进行聚合、筛选、排序等。同时增强了分面的能力,可以高效地探索数据的子集。

在开始分析探索前,我们封装一个工具方法,使得声明图表更加的简单。想了解更多 G2 的使用方法,可以去其 github 仓库。

javascript 复制代码
function g2(options) {
  const chart = new G2.Chart(); // 初始化图表
  chart.options(options); // 声明可视化
  chart.render(); // 渲染可视化
  return chart.getContainer(); // 返回并且挂载容器
}

那么接下来,我们就用这个 g2 方法去探索我们收集的数据 data。

问题0:分布

我们首先从一个简单的任务开始,只探索数据的一个维度:height,看看运动员的高度是分布如何。

这里我们使用了 point mark 去绘制了一个散点图,因为运动员的数量较多,所以这里我们设置了点的 fillOpacity 来缓解 overplotting 的问题。在这样的情况下,颜色越深的区间,运动员的数量较多;颜色越浅的区间,运动员的数量较少。下面是我们可视化的结果:

javascript 复制代码
g2({
  type: "point",
  data,
  height: 120,
  encode: { x: "height" },
  style: { shape: "point", fillOpacity: 0.2 },
  tooltip: { title: "name" }
})

可以发现大部分运动员的身高在1.6m到2m这个区间,最矮的运动员居然只有80cm,姓名是雷斯别克·托洛穆舍夫,是吉尔吉斯斯坦的一名皮划艇静水运动员,不知道是不是数据录入有误;最高的运动员是2.2m,是中国的一名篮球运动员。

当然我们也可以通过 boxplot mark 去绘制一个箱线图,更直观地了解运动员身高的分布。

javascript 复制代码
g2({
  type: "boxplot",
  data,
  coordinate: { transform: [{ type: "transpose" }] },
  height: 120,
  encode: { y: "height" }
})

问题1:相关性

完成了第一个比较简单的任务。那么接下来我们稍稍加大一点难度,这一次同时我们分析数据的三个维度:gender、sport 和 height。看看在考虑性别的情况下,运动项目和身高之间的相关性。比如什么运动的运动员身高相对较高?

这里我们同样可以使用 point mark,只不过需要对其 x,y 和 color 通道都进行编码,然后按照身高中位数进行排序。同时需要根据运动项目的数量动态计算图表高度。当然,为了更清晰的观察每个运动高度区间,我们在每个运动身高最矮和身高最高的运动员之间连一条线,最后得到如下的点线连接图:

javascript 复制代码
g2({
  type: "view",
  width: 800,
  // 去掉异常数据
  data: data.filter((d) => d.height !== 0.8 && d.height !== null),
  // 动态计算图表高度
  height: new Set(data.map((d) => d.sport)).size * 20,
  coordinate: { transform: [{ type: "transpose" }] },
  encode: {
    x: "sport",
    y: "height"
  },
  scale: { y: { nice: true } },
  axis: { y: { title: "height" } },
  children: [
    {
      type: "link",
      encode: { y1: "height" },
      // 按照 x 通道(height)分组,
      // 最小值为 y 通道,最大值为 y1 通道
      transform: [{ type: "groupX", y: "min", y1: "max" }],
      style: { strokeOpacity: 0.4, stroke: "black" },
      tooltip: null
    },
    {
      type: "point",
      encode: { color: "gender" },
      // 按照 median 中位数排序
      transform: [{ type: "sortX", by: "y", reducer: "median", reverse: true }],
      style: { shape: "point", fillOpacity: 0.2 }
    }
  ]
})

可以发现篮球和排球的运动员都普遍较高,这也符合这些运动选拔运动员的标准。同时我们可以注意到,每项运动越偏右越蓝,而蓝色代表男性,说明参加比赛的男性运动员普遍比女性运动员高。另外通过观察不同运动的 link 长度,可以发现,篮球、板球等的运动员的身高差距较大,而高尔夫、马拉松游泳等运动员的身高差距较小。

问题2:计数

上面的两个任务我们都是在分析每个运动员,属于单元可视化。接下来我们来看一些和计数相关的任务,比如第一个问题:每个国家有多少人来参加了亚运会,哪个国家最多?性别比例又是怎样的?

这里我们可以用 interval mark 去绘制一个条形图,并且将数据按照国家分组之后求和,同时对结果进行堆叠和排序,最后得到一个聚合有序的堆叠条形图。下面是我们的可视化结果:

javascript 复制代码
g2({
  type: "interval",
  width,
  data,
  encode: { x: "nation", color: "gender" },
  transform: [
    { type: "groupX", y: "count" }, // 按照 x 通道分组,将求和结果作为 y 通道的值
    { type: "stackY", orderBy: "series" }, // y 通道堆叠,同时按照性别排序
    { type: "sortX", by: "y", reverse: true } // 对 x 通道进行排序,按照 y 的大小
  ],
  scale: { y: { nice: true } },
  tooltip: { title: "nation" }
})

比较出人意料的是,中国并不是参赛选手最多的国家,最多的居然是泰国!同时有一个很有意思的现象:参赛人数越多的国家,参赛运动员的男女比例越平衡;参赛人数越少,男性参赛选手越多。比如前几名泰国、中国和韩国等国家蓝色和绿色的高度几乎一半一半,但是叙利亚、伊拉克和不丹等没有和几乎没有绿色的条。

接下来我们来看看,每个运动项目有多人参赛?性别比例又如何?

这里为了更清晰地反映男女之间的差异,我们使用一个发散条形图(Diverging Bar Chart)。这同样需要我们对数据进行分组聚合,只不过在这之前我们需要分别用 1 和 -1 代表单个男和女运动的数量,同时在聚合之后需要根据数量的绝对值进行排序。下面是我们最后可视化的结果。

javascript 复制代码
g2({
  type: "interval",
  data,
  width,
  height: 20 * new Set(data.map((d) => d.dis)).size,
  coordinate: { transform: [{ type: "transpose" }] },
  encode: {
    x: "sport",
    color: "gender",
    y: (d) => (d.gender === "男" ? 1 : -1) // 向两边求和
  },
  transform: [
    // 按照 x 通道值分组,将每一项的 y 通道求和作为组的 y 通道
    { type: "groupX", y: "sum" }, 
    // 根据绝对值求和排序
    {
      type: "sortX",
      by: "y",
      reverse: true,
      reducer: (I, V) => d3.sum(I, (i) => Math.abs(V[i])) 
    }
  ],
  scale: { y: { nice: true } },
  axis: {
    y: {
      title: "← female · male →",
      labelFormatter: (d) => `${Math.abs(+d)}` // 显示绝对值
    }
  },
  tooltip: {
    title: "sport",
    items: [{ channel: "y", valueFormatter: Math.abs }]
  }
})

可以发现参赛运动员较多的是足球和田径,不愧是运动大项。电子竞技的参赛人数如此之多还挺意外的。同时可以发现大部分运动的男女比例都相对平衡的,但是也有一些运动看上去不太平衡:

  • 电子竞技男性很多,女性很少。
  • 棒球只有男性,垒球只有女性。当然这个两个项目本来就比较特殊,男性参加的叫棒球,女性参加叫垒球。
  • 花样游泳几乎没有男性。花样游泳之前是只能女性参加的,这几年男性也可以参加了,同时本届亚运会也是第一届允许男性参加花样游泳的亚运会。
  • 艺术体操只有女性。

问题3:出生年份

现在我们来关注 birthday 这个字段,来看看参加本次运动会的运动员都是什么时候出生的?

这里我们需要使用 rect mark,在使用 binX 对数据进行分箱之后,需要使用 stackY 对数据进行堆叠。需要注意的是,原始数据里面有一些脏数据:1900年出生和2020年之后出生的,这些我们都需要先过滤掉。最后就得到了如下的一个堆叠直方图:

javascript 复制代码
g2({
  type: "rect",
  width: 800,
  // 过滤掉脏数据
  data: data.filter((d) => {
    const year = new Date(d.birthday).getFullYear();
    return year !== 1900 && year < 2020;
  }),
  encode: {
    x: (d) => new Date(d.birthday).getFullYear(), // 获取出生年份
    color: "gender"
  },
  transform: [
    { type: "binX", y: "count" }, // 对 x 通道进行分箱,求和之后最为每组的 y 通道
    { type: "stackY", orderBy: "series" }
  ],
  style: { inset: 0.5 },
  axis: { x: { title: "birthyear", tickCount: 20 } }
})

可以发现大部分运动员都是2000左右出生的,其中年龄最大的运动员大概是1940年出生的,现在已经80多岁了,是象棋运动员,而最年轻的运动员大概是15年左右出生的,目前才10岁左右,是滑板运动员。不得不感叹亚运会对年龄的包容性。

我们还可以看看每个年龄段的获奖情况,人数越多的组对应的条在越上面。

javascript 复制代码
g2({
  type: "rect",
  width: 800,
  data: data.filter((d) => {
    const year = new Date(d.birthday).getFullYear();
    return year !== 1900 && year < 2020;
  }),
  encode: {
    x: (d) => new Date(d.birthday).getFullYear(),
    color: (d) =>
      d.gold !== 0
        ? "金牌"
        : d.silver !== 0
        ? "银牌"
        : d.bronze !== 0
        ? "铜牌"
        : "无牌"
  },
  transform: [
    { type: "binX", y: "count" },
    { type: "stackY", orderBy: "value" }
  ],
  scale: {
    color: {
      domain: ["金牌", "银牌", "铜牌", "无牌"],
      range: ["#F6BD16", "#5D7092", "#CE8032", "#eee"]
    }
  },
  style: { inset: 0.5 },
  axis: { x: { title: "birthyear", tickCount: 20 } }
})

问题4:年龄和奖牌

上一个任务我们探索了出生日期,接下来我们来看看一个相关的维度:age 和奖牌之间的相关性。因为所有参赛运动员太多了,所以这里我们只关注中国的运动员。

因为涉及到了相关性,所以这里我们还是用 point mark 去绘制一个散点图,这次我们用获奖情况去编码颜色通道。同样为了考虑性别因素,我们让点向两边发散堆叠,从而得到了如下的一个发散堆叠散点图:

javascript 复制代码
g2({
  type: "view",
  width: 800,
  coordinate: { transform: [{ type: "transpose" }] },
  children: [
    {
      type: "point",
      data: data.filter((d) => d.noc === "CHN"), // 只关注中国运动员
      encode: {
        x: "age",
        y: (d) => (d.gender === "男" ? 1 : -1),
        color: (d) => // 根据获奖情况编码颜色通道
          d.gold !== 0
            ? "金牌"
            : d.silver !== 0
            ? "银牌"
            : d.bronze !== 0
            ? "铜牌"
            : "无牌",
        shape: "point"
      },
      scale: {
        x: { nice: true },
        color: { // 设置映射规则
          domain: ["金牌", "银牌", "铜牌", "无牌"],
          range: ["#F6BD16", "#5D7092", "#CE8032", "#eee"]
        }
      },
      axis: {
        y: {
          title: "← female · male →",
          labelFormatter: (d) => `${Math.abs(+d)}`
        }
      },
      // 堆叠,根据颜色排序
      transform: [{ type: "stackY", y1: "y", orderBy: "series" }],
      tooltip: {
        title: "name",
        items: [
          { field: "gold" },
          { field: "silver" },
          { field: "bronze" },
          { field: "age" }
        ]
      }
    },
    { type: "lineY", data: [0], style: { stroke: "black" } }
  ]
})

这图能获得不少有意思的信息。首先有和上一个分析任务的一致的结论:大部分参赛运动员都是2000年左右出生,所以中国大部分参赛运动员的年龄是在20到30岁之间。同时我们可以发现中国大部分女性运动员都获得了奖牌的,并且金牌获得者是最多的。相比下,男性运动员没有获得奖牌的就多不少,大概有一半左右。我们还可以发现中国的大龄运动员(40岁以上),大部分都是获得了奖牌的。

问题5:奖牌,国家和运动

上一个问题我们探索了中国个人的获奖情况,现在我们来看看每个国家和运动的获奖情况。哪些国家获和哪些运动获奖多?

因为国家和运动维度都是离散的,所以我们选择用 cell mark 绘制一个热力图,同时按照获奖人数的总数降序排序。颜色越深的块表示获奖越多,白色表示该国家的该项目没有人参加,灰色表示参加了但是没有获得任何奖牌。最后获得的可视化结果如下:

javascript 复制代码
g2({
  type: "cell",
  width: 1100,
  height: 1000,
  data,
  encode: {
    x: "sport",
    y: "nation",
    color: (d) => d.gold + d.silver + d.bronze // 每个人的奖牌总数
  },
  transform: [
    { type: "group", color: "sum" }, // 按照 x 和 y 通道分组,并对颜色通道求和
    { type: "sortY", by: "color", reverse: true }, // y 通道排序
    { type: "sortX", by: "color", reverse: true } // x 通道排序
  ],
  // 将 0 设置为 #eee 灰色
  scale: { color: { relations: [[0, "#eee"]], palette: "puRd" } },
  style: { inset: 0.5 }
})

注意:这里的总数不是奖牌榜上的总数,而是得到产生的奖牌数,因为团队运动(足球、篮球等)的一枚奖牌在奖牌榜上只会算一次,但是上图中每一个获奖运动员都会算一次。

可以发现图中白色和灰色区域不少,说明大部分国家的大部分项目都没有参加或者获奖,但是我们得为这些国家的运动员送去最高的敬意。除此之外,我们可以发现中国获奖人数是最多的,而其中游泳队又傲视群雄。这自然而然就会引出另一个问题:每个国家参赛的人数越多,就获奖越多吗?

这里我们绘制一个点线连接图来解决这个问题。首先我们需要借助 group transform 将数据按照国家分组之后,分别聚合计算总参加人数和获奖人数。然后用 point mark 去表示每一个国家,同时用 link mark 绘制一条从原点到点的线代表斜率。不难得出,斜率越大的线对应的国家获奖率(获奖人数/总人数)更高。最后的结果如下:

javascript 复制代码
g2({
  type: "view",
  encode: {
    x: 1,
    y: (d) => (d.gold + d.silver + d.bronze === 0 ? 0 : 1),
    series: "nation"
  },
  transform: [{ type: "group", channels: "series", x: "sum", y: "sum" }],
  scale: {
    x: { nice: true },
    y: { nice: true }
  },
  axis: {
    x: { title: "number of participants" },
    y: { title: "number of winners" }
  },
  children: [
    { // 绘制链接线
      type: "link",
      data,
      encode: { x1: 0, y1: 0 },
      style: { stroke: "#eee" }
    },
    { // 绘制点
      type: "point",
      data,
      labels: [
        {
          text: "nation",
          dy: 8,
          fontSize: 10,
          transform: [{ type: "overlapHide" }]
        }
      ]
    }
  ]
})

分析可以发现,总体的趋势确实是参赛人数越多获得得奖牌数越多。并且,中国不仅仅是获奖人数最多的国家,同时也是获奖效率最高的国家(斜率最大),日本和韩国也有不错的获奖效率,相对之下泰国的获奖效率就较低。

问题6:奖牌,身高和性别

通过上面一个任务我们可以发现中国的获奖数是最多的,那么接下来我们就聚焦分析中国队的得奖情况。首先我们来看看奖牌、身高和性别之间的关系。

这里我们可以用 facetRect 将数据按照获奖情况分成四个子集,分别用堆叠直方图看看身高的分布:

javascript 复制代码
g2({
  type: "facetRect",
  width: 1000,
  height: 380,
  paddingLeft: 50,
  paddingBottom: 50,
  data: data
    .filter((d) => d.noc === "CHN") // 只关注中国
    .map((d) => ({ // 生成 medal 字段,表示获奖情况
      ...d,
      medal:
        d.gold !== 0
          ? "金牌"
          : d.silver !== 0
          ? "银牌"
          : d.bronze !== 0
          ? "铜牌"
          : "无牌"
    })),
  encode: { x: "medal" },
  scale: { x: { domain: ["金牌", "银牌", "铜牌", "无牌"] } }, // 排序
  children: [
    {
      type: "rect",
      encode: { x: "height", color: "gender" },
      transform: [
        { type: "binX", y: "count" }, // 分箱
        { type: "stackY", orderBy: "series" } // 堆叠
      ],
      style: { insetLeft: 0.5 }
    }
  ]
})

通过上图我们发现金牌、银牌、铜牌的身高分布大致相同,都是在1.7和1.8m左右的人数最多。但是无牌的运动员的身高普遍较高,大部分是在1.9m和2m之间,难道身高越高,越难获得奖牌?

问题7:统计

上一个问题我们分析了奖牌、身高和性别之间的关系,在这个任务中我们把身高这个维度换成年龄看看能得到什么结果。同样我们只关注中国队的情况。

除了改变一个分析维度之外,我们也在优化一下我们的分析方法。第一,我们可以对子集继续划分,比如按照性别这个维度。第二,我们可以用 lineX mark 结合 group transform 去绘制标注线,展现年龄的中位数。最后我们得到如下的一个二维的分面直方图:

javascript 复制代码
g2({
  type: "facetRect",
  width: 1000,
  height: 560,
  paddingLeft: 50,
  paddingBottom: 50,
  data: data
    .filter((d) => d.noc === "CHN") // 只关注中国
    .map((d) => ({ // 生成 metal 字段
      ...d,
      medal:
        d.gold !== 0
          ? "金牌"
          : d.silver !== 0
          ? "银牌"
          : d.bronze !== 0
          ? "铜牌"
          : "无牌"
    })),
  encode: {
    x: "medal",
    y: "gender"
  },
  scale: {
    x: { domain: ["金牌", "银牌", "铜牌", "无牌"] },
    color: {
      // 设置颜色映射规则
      domain: ["金牌", "银牌", "铜牌", "无牌"],
      range: ["#F6BD16", "#5D7092", "#CE8032", "#eee"]
    }
  },
  children: [
    {
      type: "view",
      children: [
        {
          type: "rect",
          encode: { x: "age", color: "medal" },
          transform: [{ type: "binX", y: "count" }],
          scale: {
            color: {
              domain: ["金牌", "银牌", "铜牌", "无牌"],
              range: ["#F6BD16", "#5D7092", "#CE8032", "#eee"]
            }
          },
          style: { insetLeft: 0.5 }
        },
        { // 标注线
          type: "lineX",
          encode: { x: "age" },
          transform: [{ type: "groupColor", x: "median" }],
          style: {
            stroke: "#F4664A",
            strokeOpacity: 1,
            lineWidth: 2,
            lineDash: [4, 4]
          },
          labels: [ // 标注线文本
            {
              text: "age",
              position: "top",
              textBaseline: "top",
              textAlign: "start",
              dx: 5,
              dy: 5,
              stroke: "white",
              strokeWidth: 2
            }
          ]
        }
      ]
    }
  ]
})

可以发现获得金牌最多的年龄段是23岁,是不是意味着运动员的巅峰是23岁?男女在铜牌和无牌分布和中位数大致一致,但是男性运动员大部分是在31岁获得银牌的,女性是在22岁,这方面有较大的差异。

问题8:归约

接下来我们继续探索奖牌、年龄和性别之间的关系,只不过这一次问题可能要更加困难一点:有多少女运动员比获得该奖牌的最年轻的男性运动员小?又有多少女运动员比获得该奖牌的最年长的男性运动员大?同样我们只关注中国队的情况。

这次每一个视图我们用 point mark 去绘制一个散点图。其中女性运动员用彩色点表示,同时用一根彩色线标注年龄的中位数。男性运动员用深灰色点表示,同时用一根深灰色线标注线年龄的最小值,一根深灰色线线标注年龄的最大值。要回答上面的问题,我们只要关注有多少彩色的点在第一根深灰色线左边,和多个彩色的点在第二根深灰色线右边即可。最后我们获得可视化结果如下:

javascript 复制代码
g2({
  type: "facetRect",
  height: 320,
  width: 800,
  paddingLeft: 5,
  paddingBottom: 50,
  data: data
    .filter((d) => d.noc === "CHN") // 只关注中国
    .map((d) => ({ // 生成获奖情况的字段
      ...d,
      medal:
        d.gold !== 0
          ? "金牌"
          : d.silver !== 0
          ? "银牌"
          : d.bronze !== 0
          ? "铜牌"
          : "无牌"
    })),
  encode: { y: "medal" },
  scale: {
    y: { domain: ["金牌", "银牌", "铜牌", "无牌"] },
    color: {
      domain: ["金牌", "银牌", "铜牌", "无牌"],
      range: ["#F6BD16", "#5D7092", "#CE8032", "#eee"]
    }
  },
  children: [
    {
      type: "view",
      scale: {
        color: {
          domain: ["金牌", "银牌", "铜牌", "无牌"],
          range: ["#F6BD16", "#5D7092", "#CE8032", "#eee"]
        }
      },
      children: [
        { // 标注最小的男性运动员
          type: "lineX",
          data: {
            transform: [{ type: "filter", callback: (d) => d.gender === "男" }]
          },
          encode: { x: "age" },
          transform: [{ type: "selectX", selector: "min" }],
          style: { stroke: "grey", strokeWidth: 3, strokeOpacity: 1 }
        },
        { // 标注最大的男性运动员
          type: "lineX",
          encode: { x: "age" },
          data: {
            transform: [{ type: "filter", callback: (d) => d.gender === "男" }]
          },
          transform: [{ type: "selectX", selector: "max" }],
          style: { stroke: "grey", strokeWidth: 3, strokeOpacity: 1 }
        },
        { // 标注女性运动员年龄的中位数
          type: "lineX",
          encode: { x: "age", color: "medal" },
          data: {
            transform: [{ type: "filter", callback: (d) => d.gender === "女" }]
          },
          transform: [{ type: "selectX", selector: "median" }],
          style: { strokeWidth: 3, strokeOpacity: 1 }
        },
        { // 男性运动员
          type: "point",
          data: {
            transform: [{ type: "filter", callback: (d) => d.gender === "男" }]
          },
          encode: { x: "age", size: 2 },
          style: { shape: "point", fill: "grey" }
        },
        { // 女性运动员
          type: "point",
          data: {
            transform: [{ type: "filter", callback: (d) => d.gender === "女" }]
          },
          encode: { x: "age", color: "medal", size: 3 },
          style: { shape: "point" }
        }
      ]
    }
  ]
})

可以发现在金牌、银牌和铜牌的视图中,都有彩色点在第一根深灰色的线左边,看来"自古英雄不仅仅出少年,现在巾帼也不让须眉"。同时在金牌的视图中,我们也可以看见有不少彩色点在第二根深灰色的线右边,为这几个优秀的女性运动员点一个大大的赞。

问题9:金牌

最后我们来探索一个比较"功利"和简单的问题:哪些运动员获得的奖牌数最多?

这里我们用 interval mark 绘制一个简单的条形图就可以了,最后的结果如下:

javascript 复制代码
g2({
  type: "interval",
  height: 400,
  data: data.sort((a, b) => b.gold - a.gold).slice(0, 10),
  encode: {
    x: "name",
    y: "gold",
    color: "sport"
  },
  axis: {
    x: { labelFormatter: (d) => (d.length > 5 ? d.slice(0, 5) + "..." : d) }
  }
})

分析可得,"蝶后"张雨霏当之无愧的占领榜首,不过这清一色的蓝色条,让人不得不感叹中国游泳队的强大。除此之外,田径和乒乓球也是很容易获得多枚金牌的项目。

最后的最后,我们用词云图来看看中国运动员的热门情况(获得金牌数越高越热门),你第一眼看见了谁的名字?欢迎在评论区留言。

javascript 复制代码
g2({
  type: "wordCloud",
  padding: 0,
  data: data.filter((d) => d.noc === "CHN"),
  encode: {
    text: "name",
    value: "gold",
    color: "sport"
  },
  legend: { color: false },
  layout: { fontSize: [5, 50] },
  style: { textBaseline: "middle" }
})

洞察

到这里我们所有的分析任务都已经完成了,接下来我们就来总结一下我们获得洞察。

第一,中国队很厉害,但我们也应该为大部分未获奖参赛国家喝彩。 可以发现中国队不仅仅是获得奖牌最多的国家,同时也是获得奖牌效率最高的国家,而其中的游泳、龙舟、射击、田径和赛艇运动员的表现尤为的亮眼。同时我们也可以发现大部分国家都有很多项目没有参加,参加的也都大部分没有获得奖牌。不过还是得为这些国家运动员致以崇高的敬意,因为敢于拼搏才是奥林匹克运动会所倡导的精神。

第二,00后成为了参赛的主力军,10后也开始崭露头角。 大部分的参赛和获奖队员都是在2000到2005年这个区间出生的。这意味着为国体育争光得重担,也渐渐从90后移交到了这些20岁左右的千禧年"小孩"的手里。让人感到惊喜的是,也有不少10后的运动员出现在了赛场上并且获得奖牌,这也许就是体育精神的传承吧。

第三,年龄会影响成绩,但是"高龄运动员"也有春天。 通过分析发现,获得金牌的运动员大部分都在23岁左右,而26岁到31岁是获得银牌和铜牌的最佳年龄段,所以获得金牌和出名一样,得"趁早"。但是事情总有转机。我们发现一些大于40岁的高龄运动员也很多了不错的成绩,其中不乏金牌的获得者,当然这部分大多都是棋牌类比赛的运动员。不管怎么说,这确实也体现了亚运会对年龄的包容性,每运动员都有属于自己的获得奖牌的"时区"。

第四,大部分运动男女比例均衡,少部分失平衡。 在多数项目里面,男性运动员都比女性运动员要稍微多一点点。当然,也有个别项目(棒球、垒球、花样游泳等)因为项目性质出现运动员性别一边倒的情况。不过,一个不能忽视的事实就是:参加电子竞技的女性运动员凤毛麟角。

第五,不同运动的身高分布不同,高身高运动员获得奖牌也许更难。 和我们日常的认知一样,排球和篮球这样"巨人运动"的运动员往往具有较高的身高,而滑板运动员身高相对较矮是因为他们的年龄都相对较小。同时高尔夫球的运动员的身高差异是最小的。在分析身高和获奖情况之间的关系的时候,我们也发现没有得奖牌的运动员身高普遍偏高,也许身高越高越不容易获得奖牌?

第六,不能被忽视的中国女性力量。 这是可能这次分析最大的收获。中国大部分参赛女性运动员都获得了奖牌,这其中大部分还是金牌,相比之下参赛男性运动员几乎有一半都没有获得奖牌。另一方面,女性获奖的运动员的年龄覆盖面也更广,尤其是金牌,最小13岁,最大59岁。当然最后,我们国家金牌榜的榜首也是一位女性:游泳运动员张雨霏。这不得不让人想起了女篮决赛赛场上,观众高举的那条横幅:"无畏金兰"。

结语

这就是本篇文章的全部内容了,欢迎大家和我们讨论本次得到的结论。当然,如果大家还有更多的问题,也不用着急,毕竟数据工具思路都在这里了,还等什么?快快行动起来吧!

如果觉得本文还不错的,欢迎去给下面的工具和仓库点赞 🌟🌟🌟,你们的支持是我们最大的动力!

相关推荐
Mikhail_G1 小时前
Python初学者入门指南
大数据·运维·开发语言·python·数据分析
知否技术6 小时前
放弃ECharts!3行代码DataV搞定Vue酷炫大屏,效率飙升300%!
前端·数据可视化
cainiao0806057 小时前
基于Python的气象数据分析及可视化研究
开发语言·python·数据分析
芳菲菲其弥章10 小时前
【数据分析八:hypothesis testing】假设检验
机器学习·数据挖掘·数据分析
DolphinDB智臾科技10 小时前
如何计算股票复权因子与复权行情
数据分析·量化交易·因子挖掘·dolphindb 实时计算
武汉格发Gofartlic13 小时前
如何跟踪FEMFAT许可使用情况
运维·python·算法·信息可视化·数据分析
图扑数字孪生15 小时前
图扑 HT 3D 场景视频嵌入应用功能
3d·音视频·数字孪生·数据可视化·视频融合
是紫焅呢21 小时前
O数据可视化基础.py
python·青少年编程·信息可视化·数据分析·学习方法·数据可视化·visual studio code
是紫焅呢1 天前
N数据分析pandas基础.py
python·青少年编程·数据挖掘·数据分析·pandas·学习方法·visual studio code
界面开发小八哥1 天前
突破性能瓶颈:SciChart 高性能图表库助力大数据可视化
信息可视化·数据可视化·图表·图表工具·scichart