预计阅读 1 分钟

中国各地区城镇化率





在网上常看到一些展示你追我赶的动态图,用于需要比较的展示场合,比如ECharts 示例动态排序折线图,在论坛发了一个贴如何制作一个动态的时间序列趋势图,得到解决办法。

过去 10 年中国各地区的城镇化率数据来自国家统计局发布的 2024 年统计年鉴。

china_province <- read.table(
  header = TRUE, check.names = F,
  sep = " ", , encoding = "UTF-8", text = "
地区 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023
全国 55.75 57.33 58.84 60.24 61.50 62.71 63.89 64.72 65.22 66.16
北京 86.50 86.71 86.76 86.93 87.09 87.35 87.55 87.50 87.57 87.83
天津 82.55 82.88 83.27 83.57 83.95 84.31 84.70 84.88 85.11 85.49
河北 49.36 51.67 53.87 55.74 57.33 58.77 60.07 61.14 61.65 62.77
山西 54.30 55.87 57.27 58.59 59.85 61.29 62.53 63.42 63.96 64.97
内蒙古 60.97 62.09 63.40 64.60 65.51 66.46 67.48 68.21 68.60 69.58
辽宁 67.05 68.05 68.87 69.49 70.26 71.21 72.14 72.81 73.00 73.51
吉林 56.81 57.64 58.75 59.71 60.85 61.63 62.64 63.36 63.72 64.73
黑龙江 59.22 60.47 61.09 61.90 63.46 64.62 65.61 65.69 66.21 67.11
上海 89.30 88.53 89.00 89.10 89.13 89.22 89.30 89.30 89.33 89.46
江苏 65.70 67.49 68.93 70.18 71.19 72.47 73.44 73.94 74.42 75.04
浙江 64.96 66.32 67.72 68.91 70.02 71.58 72.17 72.66 73.38 74.23
安徽 49.31 50.97 52.62 54.29 55.65 57.02 58.33 59.39 60.15 61.51
福建 61.99 63.22 64.39 65.78 66.98 67.87 68.75 69.70 70.11 71.04
江西 50.55 52.30 53.99 55.70 57.34 59.07 60.44 61.46 62.07 63.13
山东 54.77 56.97 59.13 60.79 61.46 61.86 63.05 63.94 64.54 65.53
河南 45.05 47.02 48.78 50.56 52.24 54.01 55.43 56.45 57.07 58.08
湖北 55.73 57.18 58.57 59.88 61.00 61.83 62.89 64.09 64.67 65.47
湖南 48.98 50.79 52.70 54.62 56.09 57.45 58.76 59.71 60.31 61.16
广东 68.62 69.51 70.15 70.74 71.81 72.65 74.15 74.63 74.79 75.42
广西 46.54 47.99 49.24 50.59 51.82 52.98 54.20 55.08 55.65 56.78
海南 53.30 54.91 56.70 58.04 59.13 59.37 60.27 60.97 61.49 62.46
重庆 59.74 61.47 63.33 65.00 66.61 68.24 69.46 70.32 70.96 71.67
四川 46.51 48.27 50.00 51.78 53.50 55.36 56.73 57.82 58.35 59.49
贵州 40.24 42.96 45.56 47.76 49.54 51.48 53.15 54.33 54.81 55.94
云南 41.21 42.93 44.64 46.29 47.44 48.67 50.05 51.05 51.72 52.92
西藏 26.23 28.87 31.57 33.38 33.80 34.51 35.73 36.61 37.39 38.88
陕西 53.01 54.74 56.39 58.07 59.65 61.28 62.66 63.63 64.02 65.16
甘肃 42.28 44.24 46.07 48.12 49.69 50.70 52.23 53.33 54.19 55.49
青海 50.84 51.67 53.55 55.45 57.27 58.78 60.08 61.02 61.43 62.80
宁夏 54.82 56.98 58.74 60.95 62.15 63.63 64.96 66.04 66.34 67.31
新疆 46.79 48.78 50.42 51.90 54.01 55.51 56.53 57.26 57.89 59.24
"
)

# 重塑数据
china_province_reshape2 <- reshape(
  data = china_province,
  varying = as.character(2014:2023),
  times = 2014:2023,
  v.names = "城镇化率",
  timevar = "年份",
  idvar = "地区",
  new.row.names = 1:(10 * 32),
  direction = "long"
)

library(echarts4r)

china_province_reshape2 |>
  dplyr::mutate(
    年份 = as.character(年份), # x 轴用字符更稳
    城镇化率 = as.numeric(城镇化率) # 确保是数值
  ) |>
  dplyr::arrange(地区, 年份) |>
  dplyr::group_by(地区) |>
  e_charts(年份) |>
  e_line(
    城镇化率,
    showSymbol = FALSE,
    smooth = TRUE,
    endLabel = list(
      show = TRUE,
      formatter = htmlwidgets::JS(
        "
        function(p){
          // 优先按维度名『城镇化率』取值;否则回退为 p.value 的最后一个元素
          var idx = (p.dimensionNames && Array.isArray(p.dimensionNames))
                      ? p.dimensionNames.indexOf('城镇化率') : -1;
          var v;
          if (Array.isArray(p.value)) {
            v = (idx >= 0 ? p.value[idx] : p.value[p.value.length - 1]);
          } else if (p.value && typeof p.value === 'object' && 'value' in p.value) {
            v = p.value.value;
          } else {
            v = p.value;
          }
          return p.seriesName + ':' + (v == null || isNaN(v) ? '' : Number(v).toFixed(2));
        }
        "
      ),
      distance = 12
    ),
    labelLayout = list(moveOverlap = "shiftY"),
    emphasis = list(focus = "series")
  ) |>
  e_legend(show = FALSE) |>
  e_tooltip(trigger = "axis", order = "valueDesc") |>
  e_x_axis(type = "category", boundaryGap = FALSE) |>
  e_y_axis(name = "城镇化率") |>
  e_grid(right = 150) |> # 右侧给 endLabel 预留空间
  e_animation(duration = 10000, easing = "linear")