Vega-Lite: возможно ли построить 3-слойный график с одной осью Y, используемой только 2 определенными слоями?

#plot #graph #vega-lite #vega

#график #График #vega-lite #vega

Вопрос:

Мне интересно, как я могу построить один график с несколькими осями Y более контролируемым образом. Мой текущий график имеет уже 3 слоя, они находятся в одном и том же диапазоне значений, поэтому должны оставаться на одной оси Y. Однако теперь мне нужно нанести сверху объект совершенно другого масштаба, и мне нужна независимая ось Y только для определенных слоев. Возможно ли это?

Прямо сейчас, если я установлю resolve: scale: Y: independent , кажется, что все слои пытаются бороться за вторую ось Y, и весь сюжет растворяется.

Ниже приведен минимальный воспроизводимый пример, который можно скопировать и вставить как есть, чтобы https://vega.github.io/editor /#/ . Цель здесь состоит в том, чтобы невооруженным глазом определить наклоны всех 3 линий; другими словами, сделайте так, чтобы линии «X-Y» и «X2-Y2» использовали левую ось Y с одним масштабом, а «X3-Y3» использовали правую ось Y с совсем другой.

Пожалуйста, обратите внимание, что на самом деле у меня уже есть 6 слоев с разными типами меток, и я буду продолжать добавлять их. Однако все они будут разделены на две категории масштаба (скажем, значения от 1 до 10 и от 10000 до 20000). Я хотел бы иметь возможность определять для каждого слоя, к какой категории он относится и какую ось Y — левую или правую — он использует.

 {
  "data": {
    "values": [
      {"x": 1, "y": 10},
      {"x": 2, "y": 7},
      {"x2": 1, "y2": 11},
      {"x2": 2, "y2": 12},
      {"x3": 1, "y3": 1000},
      {"x3": 2, "y3": 2500}
    ]
  },
  "encoding": {"x": {"type": "quantitative"}, "y": {"type": "quantitative"}},
  "layer": [
    {
      "mark": "line",
      "encoding": {"x": {"field": "x"}, "y": {"field": "y"}}
      
    },
    {
      "mark": {
        "type": "square",
        "size": 100
       },
      "encoding": {
        "x": {"field": "x2"},
        "y": {"field": "y2"},
        "color": {"value": "red"}
      }
      
    },
    {
      "mark": "line",
      "encoding": {
        "x": {"field": "x3"},
        "y": {"field": "y3"},
        "color": {"value": "black"}
      }
      
    }
  ],
  "mark": "line",
  "config": {},
  "resolve": {"scale": {"y": "independent"}}
}
 

Ответ №1:

В вашем примере кода конфигурация разрешения была указана не в том месте, и поскольку вы хотели

Линии «X-Y» и «X2-Y2» используют левую ось Y с одним масштабом, а «X3-Y3» используют правую ось Y с другим масштабом.

Я разместил первые два слоя в отдельном слое, которые разделяют оси x и y, и другой слой, который будет иметь independent ось y, используя resolve.

Проверьте приведенный ниже код или ссылку на редактор:

 {
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": {
    "values": [
      {"x": 1, "y": 10},
      {"x": 2, "y": 7},
      {"x2": 1, "y2": 11},
      {"x2": 2, "y2": 12},
      {"x3": 1, "y3": 1000},
      {"x3": 2, "y3": 2500}
    ]
  },
  "encoding": {"x": {"type": "quantitative"}, "y": {"type": "quantitative"}},
  "layer": [
    {
      "layer": [
        {
          "mark": "line",
          "encoding": {"x": {"field": "x"}, "y": {"field": "y"}}
        },
        {
          "mark": "line",
          "encoding": {
            "x": {"field": "x2"},
            "y": {
              "field": "y2",
              "type": "quantitative",
              "axis": {"orient": "left"}
            },
            "color": {"value": "red"}
          }
        }
      ]
    },
    {
      "mark": "line",
      "encoding": {
        "x": {"field": "x3"},
        "y": {"field": "y3"},
        "color": {"value": "black"}
      }
    }
  ],
  "resolve": {"scale": {"y": "independent"}},
  "config": {}
}
 

Дайте мне знать, был ли это ваш ожидаемый результат.

Комментарии:

1. Большое вам спасибо за ответ. К сожалению, это не работает, хотя это работает, например, я предоставил. Причина в том, что в моей реальной ситуации мне приходится использовать разные метки для разных слоев, поэтому я не могу их объединить. Я сделаю это явным и исправлю пример, моя ошибка.

2. Исправлен пример, а также добавлен еще один поясняющий абзац.

3. Я немного подумал над проблемой, и я предполагаю, что мне просто нужно вручную указать ось для каждого слоя — по крайней мере, расположение (слева или справа) и видимость; а затем указать масштабную область для каждого слоя, чтобы убедиться, что графики фактически используют одни и те же координаты Y на каждом уровне.график.

Ответ №2:

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

 {
    "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
    "data": {
        "values": [
            {"x": 1, "y": 10},
            {"x": 2, "y": 7},
            {"x2": 1, "y2": 11},
            {"x2": 2, "y2": 12},
            {"x3": 1, "y3": 1000},
            {"x3": 2, "y3": 2500},
            {"x4": 1, "y4": 2000},
            {"x4": 2, "y4": 4000}
        ]
    },
    "encoding": {"x": {"type": "quantitative"}, "y": {"type": "quantitative"}},
    "layer": [
        {
            "mark": "line",
            "encoding": {
                "x": {"field": "x"},
                "y": {"field": "y",
                      "type": "quantitative",
                      "axis": {"orient": "left",
                               "title": "y1, y2"
                              },
                      "scale": {"domainMin": 0,
                                "domainMax": 20}
                     },
                     "color": {"value": "blue"}
            }
        },
        {
            "mark": "line",
            "encoding": {
                "x": {"field": "x2"},
                "y": {
                    "field": "y2",
                    "type": "quantitative",
                    "axis": null,
                    "scale": {"domainMin": 0,
                              "domainMax": 20}
                },
                "color": {"value": "red"}
            }
        },

        {
            "mark": "line",
            "encoding": {
                "x": {"field": "x3"},
                "y": {"field": "y3",
                      "axis": {"orient": "right",
                               "title": "y3, y4"},
                      "type": "quantitative",
                      "scale": {"domainMin": 0,
                                "domainMax": 5000}
                     },
                "color": {"value": "black"}
            }
        },

        {
            "mark": "line",
            "encoding": {
                "x": {"field": "x4"},
                "y": {"field": "y4",
                      "axis": null,
                      "type": "quantitative",
                      "scale": {"domainMin": 0,
                                "domainMax": 5000}
                     },
                "color": {"value": "cyan"}
            }
        }

    ],
    "resolve": {"scale": {"y": "independent"}},
    "config": {}
}