Public
Edited
Feb 23, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
treeData = fetch("https://data.cityofnewyork.us/resource/uvpi-gqnh.json").then(
(response) => response.json()
)
Insert cell
treeData
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
Insert cell
treeData[0].spc_common
Insert cell
Insert cell
treeSpecies = treeData.map((tree) => tree.spc_common)
Insert cell
Insert cell
uniqueTreeSpecies = new Set(treeSpecies)
Insert cell
Insert cell
viewof selectedSpecies = Inputs.select(uniqueTreeSpecies, { label: "Species" })
Insert cell
Insert cell
selectedTreeData = treeData.filter((tree) => tree.spc_common == selectedSpecies)
Insert cell
Plot.plot({
marks: [
Plot.rectY(
selectedTreeData,
Plot.binX({ y: "count" }, { x: "tree_dbh", fill: "steelblue" })
),
Plot.ruleY([0])
],
x: {
label: `Tree Diameter for ${selectedSpecies} species`
},
ariaLabel: "Distribution of tree diameters for selected species."
})
Insert cell
Insert cell
Inputs.range([0, 100], { label: "Amount", step: 1 })
Insert cell
Insert cell
Insert cell
Insert cell
viewof amount = Inputs.range([0, 100], { label: "Amount", step: 1 })
Insert cell
Insert cell
Insert cell
viewof button = Inputs.button("Click me")
Insert cell
viewof toggle = Inputs.toggle({ label: "Toggle", value: true })
Insert cell
viewof checkboxes = Inputs.checkbox(["A", "B"], {
label: "Check boxes",
value: ["A"]
})
Insert cell
viewof radios = Inputs.radio(["A", "B"], { label: "Radio buttons", value: "A" })
Insert cell
viewof date = Inputs.date({ label: "Date", value: "2022-12-22" })
Insert cell
Insert cell
Insert cell
viewof borough = Inputs.select(new Set(treeData.map((tree) => tree.boroname)), {
label: "Selected Borough",
value: "Queens"
})
Insert cell
viewof color = Inputs.color({ label: "Bars color", value: "#4682b4" })
Insert cell
viewof highlight = Inputs.color({ label: "Highlight color", value: "#ffa500" })
Insert cell
treesPerBorough = Plot.plot({
marks: [
Plot.barY(
treeData,
Plot.groupX(
{ y: "count" },
{
x: "boroname",
fill: (d) => (d.boroname === borough ? highlight : color),
sort: { x: "y", reverse: false }
}
)
),
Plot.ruleY([0])
],
marginLeft: 120,
caption: "Number of Trees per Borough",
ariaLabel: "Number of Trees per Borough"
})
Insert cell
Insert cell
Insert cell
viewof colorThreshold = Inputs.range([0, 60], {
step: 1,
label: "color threshold",
value: 10
})
Insert cell
Plot.plot({
marks: [
Plot.dot(treeData, {
x: "health",
y: "tree_dbh",
fill: (d) => d.tree_dbh > colorThreshold
})
],

y: { type: "log" },
color: { range: ["orange", "steelblue"] }
})
Insert cell
Insert cell
viewof reducer = Inputs.radio(["mean", "min", "max", "deviation", "sum"], {
value: "mean",
label: "Summary statistic (reducer):"
})
Insert cell
// lets update this code to color dots differently above and below a minimum amount paid
Plot.plot({
marks: [
Plot.barY(
treeData,
Plot.groupX(
{ y: reducer },
{
x: "health",
y: "tree_dbh",
fill: "boroname",
sort: { x: "y", reverse: true }
}
)
),
Plot.ruleY([0])
],
color: { legend: true }, // Include a legend for the fill color

caption: "Number of Trees per Borough"
})
Insert cell
Insert cell
Insert cell
nycShoreline = fetch(
"https://data.cityofnewyork.us/resource/59xk-wagz.geojson"
).then((response) => response.json())
Insert cell
Insert cell
nycBoroughs = fetch(
"https://data.cityofnewyork.us/resource/7t3b-ywvw.geojson"
).then((response) => response.json())
Insert cell
Insert cell
Plot.plot({
width: 900,
height: 600,
projection: { type: "albers", domain: nycBoroughs },
marks: [
Plot.geo(nycBoroughs, { stroke: "black", strokeOpacity: 0.3 }),
Plot.geo(nycShoreline, { stroke: "blue", strokeOpacity: 0.1 })
]
})
Insert cell
Insert cell
Plot.plot({
width: 900,
height: 600,
projection: { type: "albers", domain: nycBoroughs },
color: {
legend: true,
label: "Tree Radius",
type: "log",
range: ["red", "green"],
interpolate: "hcl" // uses d3.interpolateHcl
},
marks: [
Plot.geo(nycBoroughs, { stroke: "black", strokeOpacity: 0.3 }),
Plot.geo(nycShoreline, { stroke: "blue", strokeOpacity: 0.1 }),
Plot.dot(treeData, {
x: "longitude",
y: "latitude",
r: "tree_dbh",
// We need to parse the integers as floats to make sure we get a continuous range of colors
fill: (d) => parseFloat(d.tree_dbh)
})
]
})
Insert cell
Insert cell
Plot.plot({
width: 900,
height: 600,
projection: { type: "albers", domain: nycBoroughs },
color: {
legend: true,
label: "Tree Radius",
type: "log",
range: ["red", "green"],
interpolate: "hcl" // uses d3.interpolateHcl
},
marks: [
Plot.geo(nycBoroughs, { stroke: "black", strokeOpacity: 0.3 }),
Plot.geo(nycShoreline, { stroke: "blue", strokeOpacity: 0.1 }),
Plot.dot(treeData, {
x: "longitude",
y: "latitude",
r: "tree_dbh",
// We need to parse the integers as floats to make sure we get a continuous range of colors
fill: (d) => parseFloat(d.tree_dbh)
}),
Plot.dot(treeData, {
// Can you figure out what this additional Plot.dot layer adds?
x: "longitude",
y: "latitude",
r: "tree_dbh",
fill: (d) => parseFloat(d.tree_dbh),
stroke: "black",
filter: (d) => d.tree_dbh > 35
}),
Plot.text(treeData, {
// Add text to the map using data from treeData
x: "longitude", // Place text horizontally at plant longitude
y: "latitude", // Place text vertically at plant latitude
text: "spc_common", // The text that appears is the value from the spc_common column,
filter: (d) => d.tree_dbh > 35, // Only add text for trees wider than 35
fontSize: 14, // Increased font size
fontWeight: 600, // Increased font weight
stroke: "white", // Adds white outer stroke to text (for readability)
fill: "black", // Text fill color
textAnchor: "start", // Left align text with the x- and y-coordinates
dx: 15 // Shifts text to the right (starting from left alignment with coordinate)
})
]
})
Insert cell
Insert cell
Insert cell
viewof selectHealth = Inputs.select(
treeData.map((d) => d.health),
{
unique: true,
label: "Select tree health(s) to visualize:",
multiple: true,
value: ["Good", "Poor"]
}
)
Insert cell
Plot.plot({
width: 900,
height: 600,
projection: { type: "albers", domain: nycBoroughs },
color: {
legend: true,
label: "Tree Health"
},
marks: [
Plot.geo(nycBoroughs, { stroke: "black", strokeOpacity: 0.3 }),
Plot.geo(nycShoreline, { stroke: "blue", strokeOpacity: 0.1 }),
Plot.dot(treeData, {
x: "longitude",
y: "latitude",
r: 1,
// We need to parse the integers as floats to make sure we get a continuous range of colors
fill: "black"
}),
Plot.density(treeData, {
x: "longitude",
y: "latitude",
bandwidth: 10,
thresholds: 10,
stroke: "health",
fill: "health",
fillOpacity: 0.25,
opacity: (d) => (selectHealth.includes(d.health) ? 0.7 : 0), // (transparent unless health type selected)
mixBlendMode: "multiply",
weight: (d) => parseFloat(d.tree_dbh)
})
]
})
Insert cell
Insert cell
Plot.plot({
width: 900,
height: 600,
projection: { type: "albers", domain: nycBoroughs },
color: {
legend: true,
label: "Number of trees:",
scheme: "cool"
},
marks: [
Plot.geo(nycBoroughs, { stroke: "black", strokeOpacity: 0.3 }),
Plot.geo(nycShoreline, { stroke: "blue", strokeOpacity: 0.1 }),
Plot.dot(
treeData,
Plot.hexbin(
{ r: "count", fill: "count" },
{ x: "longitude", y: "latitude" }
)
)
]
})
Insert cell
Insert cell
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