У меня есть показатель, и я хочу отобразить цвет градиента на диаграмме с областями, соответствующий хорошему (от 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:

Попробуй это. Он не работает на 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}
}
}
}
Просто очень небольшая поправка к ответу Давиде.
{
"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/5f63025bfc0d9d32bc606d25b8615cae/…
Я попробовал здесь, и у него есть определенный потенциал, но красный цвет не отображается, когда вы поднимаетесь выше .3 vega.github.io/editor/#/gist/2ff0a3857b011fc1bf139e8e099a77f8/…