Градиент Vega-lite: укажите, где изменяется цвет относительно шкалы оси

У меня есть показатель, и я хочу отобразить цвет градиента на диаграмме с областями, соответствующий хорошему (от 0 до 0,1 = зеленый), нормальному (от > 0,1 до 0,3 = желтый), плохому (> 0,3 = красный) для этого показателя. в различные моменты времени. Как сделать точки обрезки цвета относительно фактического масштаба по оси Y?

Я думал, что смогу указать разрывы цвета с помощью смещения, и с первого прохода все выглядело правильно:

{
  "width": 600,
  "data": {
    "values": [
      {
        "__row__": 0,
        "calendar_month_year": "Dec-23",
        "concentration_risk_monthly": 0.51
      },
      {
        "__row__": 1,
        "calendar_month_year": "Jan-24",
        "concentration_risk_monthly": 0.5
      },
      {
        "__row__": 2,
        "calendar_month_year": "Feb-24",
        "concentration_risk_monthly": 0.27
      },
      {
        "__row__": 3,
        "calendar_month_year": "Mar-24",
        "concentration_risk_monthly": 0.22
      },
      {
        "__row__": 4,
        "calendar_month_year": "Apr-24",
        "concentration_risk_monthly": 0.25
      },
      {
        "__row__": 5,
        "calendar_month_year": "May-24",
        "concentration_risk_monthly": 0.22
      }
    ]
  },
  "mark": {
    "type": "area",
    "color": {
      "x1": 1,
      "y1": 1,
      "x2": 1,
      "y2": 0,
      "gradient": "linear",
      "stops": [
        {"offset": 0, "color": "#00800166"},
        {"offset": 0.3, "color": "#F7B50066"},
        {"offset": 1, "color": "#A9281F66"}
      ]
    }
  },
  "encoding": {
    "x": {
      "field": "calendar_month_year",
      "type": "ordinal",
      "sort": {"field": "__row__"},
      "axis": {"title": null},
      "scale": {"padding": 0}
    },
    "y": {
      "field": "concentration_risk_monthly",
      "type": "quantitative",
      "axis": {"title": null}
    }
  }
}

Дает:

Но если я изменю данные так, чтобы они были ниже 0,05 для этого показателя (значительно ниже 0,1 для зеленого):

{
  "width": 600,
  "data": {
    "values": [
      {
        "__row__": 0,
        "calendar_month_year": "Dec-23",
        "concentration_risk_monthly": 0.051
      },
      {
        "__row__": 1,
        "calendar_month_year": "Jan-24",
        "concentration_risk_monthly": 0.05
      },
      {
        "__row__": 2,
        "calendar_month_year": "Feb-24",
        "concentration_risk_monthly": 0.027
      },
      {
        "__row__": 3,
        "calendar_month_year": "Mar-24",
        "concentration_risk_monthly": 0.022
      },
      {
        "__row__": 4,
        "calendar_month_year": "Apr-24",
        "concentration_risk_monthly": 0.025
      },
      {
        "__row__": 5,
        "calendar_month_year": "May-24",
        "concentration_risk_monthly": 0.022
      }
    ]
  },
  "mark": {
    "type": "area",
    "color": {
      "x1": 1,
      "y1": 1,
      "x2": 1,
      "y2": 0,
      "gradient": "linear",
      "stops": [
        {"offset": 0.0, "color": "#00800166"},
        {"offset": 0.3, "color": "#F7B50066"},
        {"offset": 1.0, "color": "#A9281F66"}
      ]
    }
  },
  "encoding": {
    "x": {
      "field": "calendar_month_year",
      "type": "ordinal",
      "sort": {"field": "__row__"},
      "axis": {"title": null},
      "scale": {"padding": 0}
    },
    "y": {
      "field": "concentration_risk_monthly",
      "type": "quantitative",
      "axis": {"title": null}
    }
  }
}

Я ожидал, что вся область будет зеленой, но кажется, что смещения относятся к общей площади, и теперь красные области все еще есть, хотя все показатели ниже 0,1:

Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
3
0
117
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Попробуй это. Он не работает на 100% и очень неуклюж, но может подойти для вашего случая использования.

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "width": 600,
  "data": {
    "values": [
      {
        "__row__": 0,
        "calendar_month_year": "Dec-23",
        "concentration_risk_monthly": 0.051
      },
      {
        "__row__": 1,
        "calendar_month_year": "Jan-24",
        "concentration_risk_monthly": 0.05
      },
      {
        "__row__": 2,
        "calendar_month_year": "Feb-24",
        "concentration_risk_monthly": 0.027
      },
      {
        "__row__": 3,
        "calendar_month_year": "Mar-24",
        "concentration_risk_monthly": 0.022
      },
      {
        "__row__": 4,
        "calendar_month_year": "Apr-24",
        "concentration_risk_monthly": 0.025
      },
      {
        "__row__": 5,
        "calendar_month_year": "May-24",
        "concentration_risk_monthly": 0.022
      }
    ]
  },
  "transform": [{"extent": "concentration_risk_monthly", "param": "myExtent"}],
  "mark": {
    "type": "area",
    "fill": {
      "expr": "{'gradient': 'linear', 'x1':0,'y1':1,'x2':0,'y2':0,  'stops': [{'offset': 0, 'color': scale('stroke',  myExtent[0]>1?1:myExtent[0]>0.3?0.3:0)},{'offset': 0.3, 'color':  scale('stroke', myExtent[1]>1?1:myExtent[1]>0.3?0.3:0)},{'offset': 1, 'color':  scale('stroke', myExtent[1]>=1?1:myExtent[1]>0.3?0.3:0)}]}"
    },
    "strokeOpacity": 0
  },
  "encoding": {
    "stroke": {
      "field": "1",
      "legend": null,
      "scale": {
        "type": "linear",
        "range": ["green", "yellow", "red"],
        "domain": [0, 0.3, 1]
      }
    },
    "x": {
      "field": "calendar_month_year",
      "type": "ordinal",
      "sort": {"field": "__row__"},
      "axis": {"title": null},
      "scale": {"padding": 0}
    },
    "y": {
      "field": "concentration_risk_monthly",
      "type": "quantitative",
      "axis": {"title": null}
    }
  }
}

Я попробовал здесь, и у него есть определенный потенциал, но красный цвет не отображается, когда вы поднимаетесь выше .3 vega.github.io/editor/#/gist/2ff0a3857b011fc1bf139e8e099a77f‌​8/…

Tyler Rinker 30.05.2024 05:07
Ответ принят как подходящий

Просто очень небольшая поправка к ответу Давиде.

{
  "width": 600,
  "data": {
    "values": [
      {
        "__row__": 0,
        "calendar_month_year": "Dec-23",
        "concentration_risk_monthly": 0.8
      },
      {
        "__row__": 1,
        "calendar_month_year": "Jan-24",
        "concentration_risk_monthly": 0.7
      },
      {
        "__row__": 2,
        "calendar_month_year": "Feb-24",
        "concentration_risk_monthly": 0.7
      },
      {
        "__row__": 3,
        "calendar_month_year": "Mar-24",
        "concentration_risk_monthly": 0.8
      },
      {
        "__row__": 4,
        "calendar_month_year": "Apr-24",
        "concentration_risk_monthly": 0.8
      },
      {
        "__row__": 5,
        "calendar_month_year": "May-24",
        "concentration_risk_monthly": 0.8
      }
    ]
  },
  "transform": [{"extent": "concentration_risk_monthly", "param": "myExtent"}],
  "mark": {
    "type": "area",
   "fill": {
      "expr": "{'gradient': 'linear', 'x1':0,'y1':1,'x2':0,'y2':0,  'stops': [{'offset': 0, 'color': scale('stroke',  0)},{'offset': 0.3, 'color':  scale('stroke', myExtent[1]>1?1:myExtent[1]>0.3?0.3:0)},{'offset': 1, 'color':  scale('stroke', myExtent[1]>=1?1:myExtent[1]>0.3?1:0.3)}]}"
    },
    "strokeOpacity": 0
  },
  "encoding": {
    "stroke": {
      "field": "1",
      "legend": null,
      "scale": {
        "type": "linear",
        "range": ["#00800166", "#F7B50066", "#A9281F66"],
        "domain": [0, 0.3, 1]
      }
    },
    "x": {
      "field": "calendar_month_year",
      "type": "ordinal",
      "sort": {"field": "__row__"},
      "axis": {"title": null},
      "scale": {"padding": 0}
    },
    "y": {
      "field": "concentration_risk_monthly",
      "type": "quantitative",
      "axis": {"title": null}
    }
  }
}

И просто ради интереса вот версия с цветными полосами вместо градиента. Теперь гораздо яснее, где проходят границы.

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "width": 600,
  "data": {
    "values": [
      {
        "__row__": 0,
        "calendar_month_year": "Dec-23",
        "concentration_risk_monthly": 0.2
      },
      {
        "__row__": 1,
        "calendar_month_year": "Jan-24",
        "concentration_risk_monthly": 0.1
      },
      {
        "__row__": 2,
        "calendar_month_year": "Feb-24",
        "concentration_risk_monthly": 0.5
      },
      {
        "__row__": 3,
        "calendar_month_year": "Mar-24",
        "concentration_risk_monthly": 0.04
      },
      {
        "__row__": 4,
        "calendar_month_year": "Apr-24",
        "concentration_risk_monthly": 0.5
      },
      {
        "__row__": 5,
        "calendar_month_year": "May-24",
        "concentration_risk_monthly": 0.2
      }
    ]
  },
  "transform": [
    {"extent": "concentration_risk_monthly", "param": "myExtent"},
    {
      "joinaggregate": [
        {"op": "max", "field": "concentration_risk_monthly", "as": "maxVal"}
      ]
    }
  ],
  "encoding": {
    "x": {
      "field": "calendar_month_year",
      "type": "ordinal",
      "sort": {"field": "__row__"},
      "axis": {
        "title": null,
        "domain": false,
        "labelAngle": 0,
        "labelFontSize": 12
      },
      "scale": {"padding": 0}
    },
    "y": {
      "field": "concentration_risk_monthly",
      "type": "quantitative",
      "stack": null,
      "axis": {
        "title": null,
        "ticks": false,
        "labels": false,
        "domain": false,
        "grid": false
      }
    }
  },
  "layer": [
    {
      "transform": [
        {
          "calculate": "datum.maxVal < 0.3 ? 0.3 : datum.maxVal >= 20 ? 1 : datum.maxVal",
          "as": "redStart"
        },
        {"calculate": "0.3", "as": "redEnd"}
      ],
      "mark": {"type": "area", "color": "#A9281F66", "clip": true},
      "encoding": {
        "y": {"type": "quantitative", "field": "redStart"},
        "y2": {"field": "redEnd"}
      }
    },
    {
      "transform": [
        {
          "calculate": "datum.maxVal < 0.3 ? 0.3 : datum.maxVal >= 0.3 ? 0.3 : datum.maxVal",
          "as": "yellowStart"
        },
        {"calculate": "0.1", "as": "yellowEnd"}
      ],
      "mark": {"type": "area", "color": "#F7B50066", "clip": true},
      "encoding": {
        "y": {"type": "quantitative", "field": "yellowStart"},
        "y2": {"field": "yellowEnd"}
      }
    },
    {
      "transform": [
        {"calculate": "0.1", "as": "greenStart"},
        {"calculate": "0", "as": "greenEnd"}
      ],
      "mark": {
        "type": "area",
        "color": "#00800166",
        "opacity": 1,
        "clip": true
      },
      "encoding": {
        "y": {"type": "quantitative", "field": "greenStart"},
        "y2": {"field": "greenEnd"}
      }
    },
    {
      "mark": {"type": "line", "strokeOpacity": 1},
      "encoding": {"color": {"value": "black"}}
    },
    {
      "mark": {"type": "area"},
      "encoding": {"color": {"value": "white"}, "y2": {"value": 0}}
    },
    {
      "mark": {
        "type": "circle",
        "size": 70,
        "stroke": "black",
        "strokeWidth": 1,
        "fill": {
          "expr": "datum.concentration_risk_monthly <= 0.1 ? '#38B510' : datum.concentration_risk_monthly <= 0.3 ? '#F3CF26' : '#EC3B15'"
        }
      },
      "encoding": {"opacity": {"value": 1}}
    },
    {
      "mark": {
        "type": "rect",
        "cornerRadius": 6,
        "xOffset": {"expr": "-0"},
        "yOffset": {"expr": "-20"},
        "height": 20,
        "width": 35,
        "fill": {
          "expr": "datum.concentration_risk_monthly <= 0.1 ? '#38B510' : datum.concentration_risk_monthly <= 0.3 ? '#F3CF26' : '#EC3B15'"
        }
      }
    },
    {
      "mark": {
        "type": "text",
        "align": "center",
        "baseline": "middle",
        "xOffset": {"expr": "1"},
        "dy": -19,
        "dx": -1
      },
      "encoding": {
        "text": {
          "field": "concentration_risk_monthly",
          "type": "quantitative",
          "format": ".2f"
        },
        "color": {
          "condition": {
            "test": "datum.concentration_risk_monthly > 0.1 && datum.concentration_risk_monthly <= 0.3",
            "value": "black"
          },
          "value": "white"
        }
      }
    }
  ],
  "config": {"view": {"stroke": "transparent"}}
}

И еще один вариант с плавными линиями и тремя отдельными градиентами :)

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "usermeta": {"embedOptions": {"renderer": "svg"}},
  "width": 600,
  "data": {
    "values": [
      {
        "__row__": 0,
        "calendar_month_year": "Dec-23",
        "concentration_risk_monthly": 0.2
      },
      {
        "__row__": 1,
        "calendar_month_year": "Jan-24",
        "concentration_risk_monthly": 0.1
      },
      {
        "__row__": 2,
        "calendar_month_year": "Feb-24",
        "concentration_risk_monthly": 0.5
      },
      {
        "__row__": 3,
        "calendar_month_year": "Mar-24",
        "concentration_risk_monthly": 0.04
      },
      {
        "__row__": 4,
        "calendar_month_year": "Apr-24",
        "concentration_risk_monthly": 0.5
      },
      {
        "__row__": 5,
        "calendar_month_year": "May-24",
        "concentration_risk_monthly": 0.2
      }
    ]
  },
  "transform": [
    {"extent": "concentration_risk_monthly", "param": "myExtent"},
    {
      "joinaggregate": [
        {"op": "max", "field": "concentration_risk_monthly", "as": "maxVal"}
      ]
    }
  ],
  "encoding": {
    "x": {
      "field": "calendar_month_year",
      "type": "ordinal",
      "sort": {"field": "__row__"},
      "axis": {
        "title": null,
        "domain": false,
        "labelAngle": 0,
        "labelFontSize": 10
      },
      "scale": {"padding": 0}
    },
    "y": {
      "field": "concentration_risk_monthly",
      "type": "quantitative",
      "stack": null,
      "axis": {
        "title": null,
        "ticks": false,
        "labels": false,
        "domain": false,
        "grid": false,
        "labelPadding": 5,
        "labelFontSize": 10
      }
    }
  },
  "layer": [
    {
      "transform": [
        {
          "calculate": "datum.maxVal < 0.3 ? 0.3 : datum.maxVal >= 20 ? 1 : datum.maxVal",
          "as": "redStart"
        },
        {"calculate": "0.3", "as": "redEnd"}
      ],
      "mark": {
        "type": "area",
        "interpolate": "monotone",
        "clip": true,
        "color": {
          "x1": 1,
          "y1": 1,
          "x2": 1,
          "y2": 0.3,
          "gradient": "linear",
          "stops": [
            {"offset": 0, "color": "#FFC600"},
            {"offset": 1, "color": "#FE3800"}
          ]
        }
      },
      "encoding": {
        "y": {"type": "quantitative", "field": "redStart"},
        "y2": {"field": "redEnd"}
      }
    },
    {
      "transform": [
        {
          "calculate": "datum.maxVal < 0.3 ? 0.3 : datum.maxVal >= 0.3 ? 0.3 : datum.maxVal",
          "as": "yellowStart"
        },
        {"calculate": "0.1", "as": "yellowEnd"}
      ],
      "mark": {
        "type": "area",
        "interpolate": "monotone",
        "clip": true,
        "color": {
          "x1": 1,
          "y1": 1,
          "x2": 1,
          "y2": 0.1,
          "gradient": "linear",
          "stops": [
            {"offset": 0, "color": "#C9F047"},
            {"offset": 1, "color": "#FFC600"}
          ]
        }
      },
      "encoding": {
        "y": {"type": "quantitative", "field": "yellowStart"},
        "y2": {"field": "yellowEnd"}
      }
    },
    {
      "transform": [
        {"calculate": "0.1", "as": "greenStart"},
        {"calculate": "0", "as": "greenEnd"}
      ],
      "mark": {
        "type": "area",
        "interpolate": "monotone",
        "opacity": 1,
        "clip": true,
        "color": {
          "x1": 1,
          "y1": 1,
          "x2": 1,
          "y2": 0.1,
          "gradient": "linear",
          "stops": [
            {"offset": 0, "color": "#1AA60C"},
            {"offset": 1, "color": "#C9F047"}
          ]
        }
      },
      "encoding": {
        "y": {"type": "quantitative", "field": "greenStart"},
        "y2": {"field": "greenEnd"}
      }
    },
    {
      "transform": [{"calculate": "0.1", "as": "yellowBorder"}],
      "mark": {
        "type": "line",
        "strokeWidth": 1,
        "strokeDash": [2, 2],
        "color": "black"
      },
      "encoding": {"y": {"field": "yellowBorder"}}
    },
    {
      "transform": [{"calculate": "0.3", "as": "redBorder"}],
      "mark": {
        "type": "line",
        "strokeWidth": 1,
        "strokeDash": [2, 2],
        "color": "black"
      },
      "encoding": {"y": {"field": "redBorder"}}
    },
    {
      "mark": {
        "type": "area",
        "interpolate": "monotone",
        "stroke": "white",
        "strokeWidth": 1
      },
      "encoding": {"color": {"value": "white"}, "y2": {"value": 0}}
    },
    {
      "mark": {"type": "line", "strokeWidth": 1, "interpolate": "monotone"},
      "encoding": {"color": {"value": "black"}}
    },
    {
      "mark": {
        "type": "circle",
        "size": 70,
        "stroke": "black",
        "strokeWidth": 1,
        "fill": {
          "expr": "datum.concentration_risk_monthly <= 0.1 ? '#38B510' : datum.concentration_risk_monthly <= 0.3 ? '#F3CF26' : '#EC3B15'"
        }
      },
      "encoding": {"opacity": {"value": 1}}
    },
    {
      "mark": {
        "type": "text",
        "align": "left",
        "baseline": "middle",
        "xOffset": {"expr": "1"},
        "dy": 0,
        "dx": 12,
        "color": "black",
        "angle": 270
      },
      "encoding": {
        "text": {
          "field": "concentration_risk_monthly",
          "type": "quantitative",
          "format": ".2f"
        }
      }
    }
  ],
  "config": {"view": {"stroke": "white", "strokeWidth": 3}}
}

так близко, но если в эту область не попадают никакие значения, цвет не будет отображаться. Например, если все значения выше . 7 зеленый не появляется. vega.github.io/editor/#/gist/5f63025bfc0d9d32bc606d25b8615ca‌​e/…

Tyler Rinker 30.05.2024 16:54

Другие вопросы по теме