Санкейту рассказывает вам истории рабочих-мигрантов

визуализация данных
Санкейту рассказывает вам истории рабочих-мигрантов

Общественный номер: You Er Hut
Автор: Питер
Редактор: Питер

Всем привет, меня зовут Питер~

Санкейту рассказывает вам истории рабочих-мигрантов

В этой статье рассказывается об использовании Plotly для рисования относительно редкой визуализации:Диаграмма Санкиможно сказать, что этот график является мощным инструментом для отображения потока данных.

Хотя частота использования диаграмм Санки не так высока, как у гистограмм и круговых диаграмм, мне все равно очень нравится этот график.

Когда я впервые столкнулся с диаграммой Санки, она была нарисована с помощью Pyehcarts (этот отечественный артефакт визуализации будет специально представлен в будущем).Эта статья расскажет, как использовать Plotly для реализации этого графа.

Введение в диаграммы Санки

1.1 Что такое диаграмма Санки

Диаграмма Санки (диаграмма Санки), то есть диаграмма распределения энергии Санки, также известная как диаграмма энергетического баланса Санки. Он описывает перетекание одного набора значений в другой и представляет собой специфический тип потокового графа. Санки, на самом деле, имя человека, полное имя:Мэтью Генри Финеас Риалл Санки, был инженером ирландского происхождения и капитаном Инженерного корпуса Королевской армии.

В 1898 году он использовал этот вид графика для представления энергоэффективности паровых машин.Он впервые представил первую диаграмму потока энергии в статье об энергоэффективности паровых машин в Трудах Общества инженеров-строителей.Имя названо Карта Санки, а китайская транслитерация — карта Санки:

На приведенном ниже рисунке представлена ​​карта русской кампании Наполеона 1812 года, нарисованная Шарлем Минаром в 1869 году, которая представляет собой блок-схему, накладывающую диаграмму Санки на карту, графическое представление представляет собой сравнение сил атакующей и отступающей армии Наполеона:

1.2 Особенности диаграммы Санки

Основные особенности диаграммы Санки:

  1. Начальный поток и конечный поток одинаковы, сумма ширин всех основных ветвей и ширин всех разветвленных ветвей одинакова, что обеспечивает сохранение энергии
  2. Внутри диаграммы Санки разные линии представляют разные распределения потоков, а разная ширина узлов представляет поток в определенном состоянии.

Три элемента диаграммы Санки: узел, поток, ребро

Диаграммы Санки часто используются для визуального анализа данных в области энергетики, состава материалов и финансов. В конце этой статьи я объясню практический пример из жизни, чтобы проиллюстрировать использование диаграмм Санки.

Посмотрите на другой пример диаграммы Санки: экономическое положение страны.

2. Базовая диаграмма Санки

В следующем примере представлена ​​базовая диаграмма Санки, основанная на plotly.graph_objects:

import pandas as pd
import numpy as np

import plotly_express as px
import plotly.graph_objects as go

# 构造数据

label = ["节点0", "节点1", "节点2", "节点3", "节点4", "节点5"]
# source和target是label中对应元素的索引值,python列表从0开始
source = [0, 0, 0, 1, 1, 0]  # 可以看做父级节点
target = [2, 3, 5, 4, 5, 4]  # 子级节点
value = [9, 3, 6, 2, 7, 8]   # value是连接source和target之间的值
 
# 生成绘图需要的字典数据
link = dict(source = source, target = target, value = value)
node = dict(label = label, pad=200, thickness=20)  # 节点数据,间隔和厚度设置

# 添加绘图数据
data = go.Sankey(link = link, node=node)

# 绘图并显示
fig = go.Figure(data)
fig.show()

Чтобы объяснить приведенный выше код рисования, нам нужно подготовить следующие данные:

  • label: имя каждого узла, вы можете назвать его самостоятельно
  • soure: родительский узел, который представлен индексом узла в plotly, который начинается с 0 в python
  • цель: дочерний узел, где потоки данных
  • значение: значение, соединяющее родительский узел и дочерний узел

Другой способ написания:

fig = go.Figure(data=[go.Sankey(
    node = dict(
      pad = 200,
      thickness = 20,
      line = dict(color = "black", width = 0.1),
      label = ["节点0", "节点1", "节点2", "节点3", "节点4", "节点5"],
      color = "blue"
    ),
    link = dict(
      source = [0, 0, 0, 1, 1, 0], # 对应label的索引值
      target = [2, 3, 5, 4, 5, 4],
      value = [9, 3, 6, 2, 7, 8]
  ))])

fig.update_layout(title_text="Plotly绘制桑基图", font_size=10)
fig.show()

3. Диаграмма Санки на основе данных формата файла json

На официальном сайте plotly есть такой пример: скачайте json-файл с заданного сайта, чтобы нарисовать диаграмму Санки, и объясните его шаг за шагом:

1. Прочитайте файл json и преобразуйте его в данные словаря Python.

import urllib, json  # 同时导入多个库包

url = 'https://raw.githubusercontent.com/plotly/plotly.js/master/test/image/mocks/sankey_energy.json'
response = urllib.request.urlopen(url)  # 获取json文件
data = json.loads(response.read())   # json文件转成python字典

Как вывести данные в формате словаря в файл json и украсить формат?

with open("sankey.json","a",encoding="utf-8") as f:
    json.dump(data,   # 待写入数据
              f, # File对象
              indent=2,  # 空格缩进符,写入多行
              sort_keys=True,  # 键的排序
              ensure_ascii=False)  # 显示中文

Примерный формат украшенного файла (частичный скриншот):

opacity = 0.6   # 透明度设置

fig = go.Figure(data=[go.Sankey(
    valueformat = ".0f",
    valuesuffix = "TWh",
    
    # 节点定义
    node = dict(
      pad = 15,  # 间隔
      thickness = 15,  # 边的宽度
      line = dict(color = "black", width = 0.5),
      label =  data['data'][0]['node']['label'],  # 数据中对应的标签和颜色
      color =  data['data'][0]['node']['color']
    ),
    
    # 连接数据
    link = dict(  # 父节点、子节点、流量的值、节点名称、颜色设置
      source =  data['data'][0]['link']['source'],
      target =  data['data'][0]['link']['target'],
      value =  data['data'][0]['link']['value'],
      label =  data['data'][0]['link']['label'],
      color =  data['data'][0]['link']['color']
))])

# 重点:标题中可以使用html标签
fig.update_layout(title_text="Plotly读取json文件绘制桑基图 via <a href='https://bost.ocks.org/mike/sankey/'>Mike Bostock</a>",
                  font_size=10)
fig.show()

Вы также можете установить цвет фона графики:

import plotly.graph_objects as go
import urllib, json

# 在线读取数据并转成字典格式
url = 'https://raw.githubusercontent.com/plotly/plotly.js/master/test/image/mocks/sankey_energy.json'
response = urllib.request.urlopen(url)
data = json.loads(response.read())

# 设置图片的参数
fig = go.Figure(data=[go.Sankey(
    valueformat = ".0f",
    valuesuffix = "TWh",
    node = dict(
      pad = 15,
      thickness = 15,
      line = dict(color = "black", width = 0.5),
      label =  data['data'][0]['node']['label'],
      color =  data['data'][0]['node']['color']
    ),
    link = dict(
      source =  data['data'][0]['link']['source'],
      target =  data['data'][0]['link']['target'],
      value =  data['data'][0]['link']['value'],
      label =  data['data'][0]['link']['label']
  ))])

# 进行背景色的设置
fig.update_layout(
    hovermode = 'x',
    title="桑基图绘制_改变背景色",
    font=dict(size = 10, color = 'white'),
    plot_bgcolor='green',
    paper_bgcolor='black'   # 整个图的背景(黑色部分)
)

fig.show()

Четыре характерные диаграммы Санки

4.1 «Диаграмма Санки» для пользовательского местоположения

Диаграмма Санки, нарисованная здесь, предназначена для настройки положения узла по xy:

import plotly.graph_objects as go

fig = go.Figure(go.Sankey(
    arrangement = "snap",
    node = {
        "label": ["节点0", "节点1", "节点2", "节点3", "节点4", "节点5"], # 节点名称
        "x": [0.2, 0.1, 0.5, 0.7, 0.3, 0.5],   # xy来决定位置
        "y": [0.6, 0.5, 0.2, 0.4, 0.2, 0.5],
        'pad':1},  # 间隔
    link = {
        "source": [0, 0, 1, 2, 3, 4, 3, 5], # 父子节点和流量值
        "target": [5, 3, 4, 3, 0, 2, 2, 3],
        "value": [8, 12, 12, 11, 11, 10, 11, 12]}))

fig.show()

Судя по графике, начало координат всего холста должно быть в верхнем левом углу, горизонтальная ось направлена ​​положительно вправо, а вертикальная ось направлена ​​положительно вниз.

4.2 Настройка цвета узлов и ребер

Цвет узлов и ребер диаграммы Санки можно настроить с помощью параметров color_mode и color_link:

import plotly.graph_objects as go

# 构造节点数据

label = ["节点0", "节点1", "节点2", "节点3", "节点4", "节点5"]
source = [0, 0, 0, 1, 1, 0]
target = [2, 3, 5, 4, 5, 4]
value = [9, 3, 6, 2, 7, 8]  


# 自定义颜色
color_node = ['#E8C9B0', '#48C9B0', '#A8C9B0','#AF7AC5', '#AF7AC5', '#AF7AC5']

color_link = ['#A6E3D7', '#D6E3D7', '#A6E3D7','#CBB4D5', '#CBB4D5', '#CBB4D5']
 
# 生成绘图需要的字典数据
link = dict(source = source, target = target, value = value, color=color_link)
node = dict(label = label, pad=200, thickness=20, color=color_node)  # 节点数据,间隔和厚度设置

# 添加绘图数据
data = go.Sankey(link = link, node=node)

# 绘图并显示
fig = go.Figure(data)
fig.show()

5. Диаграмма Санки_ежемесячные расходы

Ниже приводится объяснение того, как нарисовать диаграмму Санки на основе фактических данных на основе общих расходов Сяо Мина за один месяц.

1. Во-первых, давайте посмотрим на данные о потреблении (виртуальные данные), собранные Сяо Мином.

Расходы Сяо Мина в основном разделены на 5 основных блоков: проживание, питание, питание, транспорт, одежда и красные конверты.Каждый блок разделен на свои подблоки и соответствующее потребление.

2. Организуйте данные, чтобы показать потребление от родителя к ребенку

Поскольку для рисования диаграммы Санки требуются данные между родительским и дочерним узлами, нам нужно сначала загрузить данные целиком:

На следующем графике представлены данные сопоставления для 5 основных блоков:

На следующем рисунке показано сопоставление родительских и дочерних данных, соответствующих каждому подблоку:

Детали:Санкейту рассказывает вам истории рабочих-мигрантов