Public
Edited
May 2
Insert cell
Insert cell
vis1 = Plot.plot({
// subtitle: "Співвідношення цін на автомобілі в деклараціях і на ринку",
style: { fontWeight: 400, fontSize: 14 },
width: width > 650 ? 650 : 350,
height: width > 650 ? 550 : 350,
marginBottom: 50,
marginTop: 50,
marginLeft: 50,
// color: {
// type: "log",
// range: ["#00A69C", "#EA7E34"]
// },
y: {
domain: [0, 3000000],
tickFormat: (d) => d / 1000000 + " млн",
ticks: 4,
label: "Ціни з оголошень, грн",
nice: true
},
grid: true,
x: {
domain: [0, 3000000],
tickFormat: (d) => d / 1000000 + " млн",
ticks: 4,
label: "Ціни з декларацій, грн",
nice: true
},
marks: [
Plot.dot(data, {
x: "price",
y: "amount",
fill: "blue",
opacity: 0.4,
tip: true,
title: (d) => `${d.car_name.toUpperCase()}`,
r: 3.5,
// fill: (d) => Math.abs(d.amount - d.price)
fill: (d) => (d.amount - d.price > 0 ? "#00A69C" : "#EA7E34")
}),
Plot.link([0], {
x1: 0,
y1: 0,
x2: 3000000,
y2: (k) => 3000000
}),
Plot.text(["Однакові ціни"], {
frameAnchor: "middle",
textAnchor: "middle",
dx: 60,
dy: width > 650 ? -58 : -46,
fontSize: 12,
fontWeight: 400,
lineWidth: 12,
rotate: width > 650 ? -37 : -40
}),
Plot.text(["Вища вартість на ринку"], {
frameAnchor: "top-left",
textAnchor: "middle",
dx: 50,
dy: 50,
fontSize: 16,
fontWeight: 600,
lineWidth: 12
}),
Plot.text(["Вища вартість в деклараціях"], {
frameAnchor: "bottom-right",
textAnchor: "middle",
dx: -50,
dy: -50,
fontSize: 16,
fontWeight: 600,
lineWidth: 12
})

// Plot.hexgrid(),
// Plot.dot(
// data,
// Plot.hexbin(
// { r: "count" },
// { x: "price", y: "amount", fill: "currentColor" }
// )
// )
]
})
Insert cell
data = (await FileAttachment("declaration_auto.csv").csv()).map((d) => {
return {
...d,
price: +d.price,
amount: +d.amount,
date: new Date(d.date),
date2: new Date(d.graduationYear)
};
})
Insert cell
Insert cell
vis2 = {
let data_ = data.filter((d) => d.date2 > new Date("2009-01-01"));

return Plot.plot({
// subtitle:
// "Середня ціна на бренд і марку автомобіля, в залежності від року випуску",
style: { fontWeight: 400, fontSize: 14 },
width: width > 650 ? 650 : 350,
height: 350,
marginLeft: 60,
marginRight: width > 650 ? 60 : 60,
y: {
// domain: [0, 3000000],
tickFormat: (d) => d / 1000000 + " млн",
ticks: 4,
label: null,
labelArrow: null,
grid: true,
nice: true
},
x: { label: null },
marks: [
// Plot.dot(data_, { x: "date2", y: "price", fill: "blue", opacity: 0.1 }),
Plot.lineY(
data_,
Plot.binX(
{ y: "median" },
{
x: "date2",
y: "amount",
interval: "year",
stroke: "#00A69C",
strokeWidth: 2.5
}
)
),
Plot.dot(
data_,
Plot.binX(
{ y: "median" },
{
x: "date2",
y: "amount",
interval: "year",
fill: "#00A69C",
strokeWidth: 2.5
}
)
),
Plot.lineY(
data_,
Plot.binX(
{ y: "median" },
{
x: "date2",
y: "price",
interval: "year",
stroke: "#EA7E34",
strokeWidth: 2.5
}
)
),
Plot.dot(
data_,
Plot.binX(
{ y: "median" },
{
x: "date2",
y: "price",
interval: "year",
fill: "#EA7E34",
strokeWidth: 2.5
}
)
),
Plot.text(["Ціни на ринку"], {
x: new Date("2019-01-01"),
y: 850000,
dx: width > 650 ? 0 : -10,
dy: -5,
rotate: width > 650 ? -20 : -45,
fill: "#00A69C",
fontSize: 16,
fontWeight: 600
}),
Plot.text(["Ціни з декларацій"], {
x: new Date("2019-01-01"),
y: 500000,
dy: -10,
dx: width > 650 ? -10 : -5,
rotate: width > 650 ? -20 : -50,
fill: "#EA7E34",
fontSize: 16,
fontWeight: 600
}),
Plot.arrow([0], {
x1: new Date("2024-11-01"),
x2: new Date("2024-08-01"),
y1: 900000,
y2: 1300000,
bend: -30,
dx: 0,
dy: 5
}),
Plot.text(
["Для нових автомобілів ціни в деклараціях і ціни на ринку збігаються"],
{
// textAnchor: "end",
x: new Date("2024-06-01"),
y: 750000,
dy: 20,
dx: width > 650 ? 10 : 15,
fontSize: 16,
fontWeight: 300,
lineWidth: width > 650 ? 10 : 8
}
),
Plot.ruleY([0])
]
});
}
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more