This article talks about the performing data analysis and building data visualizations for Air pollutants data from Our World in Data.
1. Data Source
Data for
- Air pollutants [Link]
2. Ingest Data
File attachement.
3. Explore Data
4. Data transformations
SELECT COUNT(*) AS "Total_Rows"
FROM airPollution
5. Visualize data
5.1 Card
<div class="main-container" style="">
<div class="container">
<svg class="color1" viewBox="0 0 465 408" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_11)">
<path d="M131.708 242.056C147.41 133.679 218.698 131.25 252.379 143.583C257.225 132.578 277.604 117.172 320.348 143.583C341.429 160.09 350.806 159.976 351.969 225.549C353.132 291.122 320.953 311.69 304.718 313.777H202.584C172.416 335.027 116.006 350.434 131.708 242.056Z" />
</g>
<defs>
<filter id="filter0_f_1_11" x="0" y="0" width="481" height="458" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="64.5" result="effect1_foregroundBlur_1_11" />
</filter>
</defs>
</svg>
<svg class="color2" viewBox="0 0 378 405" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_5)">
<path d="M215.096 264.863C231.993 207.121 162.183 120.603 220.473 144.628C278.763 168.652 325.84 241.568 308.943 299.309C292.045 357.051 217.573 377.753 159.283 353.729C100.993 329.704 198.198 322.604 215.096 264.863Z" fill="url(#paint0_linear_1_5)" />
</g>
<defs>
<filter id="filter0_f_1_5" x="0.866425" y="0.511726" width="451.556" height="503.05" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="70" result="effect1_foregroundBlur_1_5" />
</filter>
<linearGradient id="paint0_linear_1_5" x1="208.732" y1="374.109" x2="291.285" y2="173.813" gradientUnits="userSpaceOnUse">
<stop stop-color="" />
<stop offset="1" stop-color="" stop-opacity="" />
</linearGradient>
</defs>
</svg>
<svg class="color3" viewBox="0 0 423 518" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_4)">
<path d="M326.284 357.156C301.741 343.549 238.633 204.487 252.688 168.783C266.743 133.079 298.094 159.882 362.008 211.727C386.551 225.334 410.226 281.442 396.172 317.146C382.117 352.85 350.827 370.763 326.284 357.156Z" fill="url(#paint0_linear_1_4)"/>
</g>
<defs>
<filter id="filter0_f_1_4" x="0.670303" y="-97.5213" width="649.706" height="709.232" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="125" result="effect1_foregroundBlur_1_4"/>
</filter>
<linearGradient id="paint0_linear_1_4" x1="297.488" y1="320.285" x2="409.279" y2="303.653" gradientUnits="userSpaceOnUse">
<stop stop-color=""/>
<stop offset="1" stop-color="" stop-opacity=""/>
</linearGradient>
</defs>
</svg>
<div class="card" style="padding: 0rem 3rem 0rem 3rem; ">
<p style="font-size:1rem; opacity: 1;">
TotalRows
</p>
<p style="opacity: 1;">
${TotalRows[0].Total_Rows}
</p>
</div>
</div>
</div>
5.2 Nitrogen oxide (NOx) trend
Plot.plot({
marks: [
Plot.ruleY([0]),
Plot.ruleX(airPollution, {
x: "Year",
y: "Nitrogen oxide (NOx)",
tip: true
})
],
width,
marginBottom: 60,
marginLeft: 60
})
5.3 Nitrogen oxide (NOx) trend for selective countries
<div class="main-container" style="">
<div class="container">
<svg class="color1" viewBox="0 0 465 408" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_11)">
<path d="M131.708 242.056C147.41 133.679 218.698 131.25 252.379 143.583C257.225 132.578 277.604 117.172 320.348 143.583C341.429 160.09 350.806 159.976 351.969 225.549C353.132 291.122 320.953 311.69 304.718 313.777H202.584C172.416 335.027 116.006 350.434 131.708 242.056Z" />
</g>
<defs>
<filter id="filter0_f_1_11" x="0" y="0" width="481" height="458" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="64.5" result="effect1_foregroundBlur_1_11" />
</filter>
</defs>
</svg>
<svg class="color2" viewBox="0 0 378 405" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_5)">
<path d="M215.096 264.863C231.993 207.121 162.183 120.603 220.473 144.628C278.763 168.652 325.84 241.568 308.943 299.309C292.045 357.051 217.573 377.753 159.283 353.729C100.993 329.704 198.198 322.604 215.096 264.863Z" fill="url(#paint0_linear_1_5)" />
</g>
<defs>
<filter id="filter0_f_1_5" x="0.866425" y="0.511726" width="451.556" height="503.05" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="70" result="effect1_foregroundBlur_1_5" />
</filter>
<linearGradient id="paint0_linear_1_5" x1="208.732" y1="374.109" x2="291.285" y2="173.813" gradientUnits="userSpaceOnUse">
<stop stop-color="" />
<stop offset="1" stop-color="" stop-opacity="" />
</linearGradient>
</defs>
</svg>
<svg class="color3" viewBox="0 0 423 518" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_4)">
<path d="M326.284 357.156C301.741 343.549 238.633 204.487 252.688 168.783C266.743 133.079 298.094 159.882 362.008 211.727C386.551 225.334 410.226 281.442 396.172 317.146C382.117 352.85 350.827 370.763 326.284 357.156Z" fill="url(#paint0_linear_1_4)"/>
</g>
<defs>
<filter id="filter0_f_1_4" x="0.670303" y="-97.5213" width="649.706" height="709.232" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="125" result="effect1_foregroundBlur_1_4"/>
</filter>
<linearGradient id="paint0_linear_1_4" x1="297.488" y1="320.285" x2="409.279" y2="303.653" gradientUnits="userSpaceOnUse">
<stop stop-color=""/>
<stop offset="1" stop-color="" stop-opacity=""/>
</linearGradient>
</defs>
</svg>
<div class="card" style="width:95%; height:100%; font-size:2rem;">
${(() => {
const data = airPollution.filter((d) =>
["United Kingdom", "United States", "India", "China", "World"].includes(
d.Entity
)
);
return Plot.plot({
marks: [
Plot.line(data, {
x: "Year",
y: "Nitrogen oxide (NOx)",
z: "Entity",
stroke: "Entity",
tip: true
}),
Plot.ruleX(
data,
Plot.pointerX({
x: "Year",
py: "Nitrogen oxide (NOx)",
z: "Entity",
stroke: "red"
})
),
Plot.dot(
data,
Plot.pointerX({
x: "Year",
y: "Nitrogen oxide (NOx)",
z: "Entity",
stroke: "red"
})
),
Plot.text(
data,
Plot.selectLast({
x: "Year",
y: "Nitrogen oxide (NOx)",
z: "Entity",
text: "Entity",
textAnchor: "start",
dx: -3,
dy: 9
})
)
],
y: {
type: "linear",
grid: true,
nice: true,
tickFormat: (d) => d === 0 ? "0" : (d / 1e6) + "M t", // Format tick values in millions and append "t"
domain: [0, 140000000], // Set the maximum value to 140M
ticks: 8 // Set the number of ticks to 8, with a step of 20M
},
color: {
scheme: "spectral",
legend: true
},
title: "Nitrogen oxide (NOx) trend",
width,
marginLeft: 70,
});
})()}
</div>
</div>
</div>
5.4 Sulphur dioxide (SO₂) emissions trend for selective countries
<div class="main-container" style="">
<div class="container">
<svg class="color1" viewBox="0 0 465 408" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_11)">
<path d="M131.708 242.056C147.41 133.679 218.698 131.25 252.379 143.583C257.225 132.578 277.604 117.172 320.348 143.583C341.429 160.09 350.806 159.976 351.969 225.549C353.132 291.122 320.953 311.69 304.718 313.777H202.584C172.416 335.027 116.006 350.434 131.708 242.056Z" />
</g>
<defs>
<filter id="filter0_f_1_11" x="0" y="0" width="481" height="458" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="64.5" result="effect1_foregroundBlur_1_11" />
</filter>
</defs>
</svg>
<svg class="color2" viewBox="0 0 378 405" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_5)">
<path d="M215.096 264.863C231.993 207.121 162.183 120.603 220.473 144.628C278.763 168.652 325.84 241.568 308.943 299.309C292.045 357.051 217.573 377.753 159.283 353.729C100.993 329.704 198.198 322.604 215.096 264.863Z" fill="url(#paint0_linear_1_5)" />
</g>
<defs>
<filter id="filter0_f_1_5" x="0.866425" y="0.511726" width="451.556" height="503.05" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="70" result="effect1_foregroundBlur_1_5" />
</filter>
<linearGradient id="paint0_linear_1_5" x1="208.732" y1="374.109" x2="291.285" y2="173.813" gradientUnits="userSpaceOnUse">
<stop stop-color="" />
<stop offset="1" stop-color="" stop-opacity="" />
</linearGradient>
</defs>
</svg>
<svg class="color3" viewBox="0 0 423 518" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_4)">
<path d="M326.284 357.156C301.741 343.549 238.633 204.487 252.688 168.783C266.743 133.079 298.094 159.882 362.008 211.727C386.551 225.334 410.226 281.442 396.172 317.146C382.117 352.85 350.827 370.763 326.284 357.156Z" fill="url(#paint0_linear_1_4)"/>
</g>
<defs>
<filter id="filter0_f_1_4" x="0.670303" y="-97.5213" width="649.706" height="709.232" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="125" result="effect1_foregroundBlur_1_4"/>
</filter>
<linearGradient id="paint0_linear_1_4" x1="297.488" y1="320.285" x2="409.279" y2="303.653" gradientUnits="userSpaceOnUse">
<stop stop-color=""/>
<stop offset="1" stop-color="" stop-opacity=""/>
</linearGradient>
</defs>
</svg>
<div class="card" style="width:95%; height:100%; font-size:2rem;">
${(() => {
const data = airPollution.filter((d) =>
["United Kingdom", "United States", "India", "China", "World"].includes(
d.Entity
)
);
return Plot.plot({
marks: [
Plot.line(data, {
x: "Year",
y: "Sulphur dioxide (SO₂) emissions",
z: "Entity",
stroke: "Entity",
tip: true
}),
Plot.ruleX(
data,
Plot.pointerX({
x: "Year",
py: "Sulphur dioxide (SO₂) emissions",
z: "Entity",
stroke: "red"
})
),
Plot.dot(
data,
Plot.pointerX({
x: "Year",
y: "Sulphur dioxide (SO₂) emissions",
z: "Entity",
stroke: "red"
})
),
Plot.text(
data,
Plot.selectLast({
x: "Year",
y: "Sulphur dioxide (SO₂) emissions",
z: "Entity",
text: "Entity",
textAnchor: "start",
dx: -3,
dy: 9
})
)
],
y: {
type: "linear",
grid: true,
nice: true,
tickFormat: (d) => d === 0 ? "0" : (d / 1e6) + "M t", // Format tick values in millions and append "t"
domain: [0, 140000000], // Set the maximum value to 140M
ticks: 8 // Set the number of ticks to 8, with a step of 20M
},
color: {
scheme: "spectral",
legend: true
},
title: "Sulphur dioxide (SO₂) emissions Trend",
width,
marginLeft: 70
});
})()}
</div>
</div>
</div>
styles
<style>
:root {
--theme-foreground: #1b1e23;
--theme-foreground-focus: #3b5fc0;
--theme-background-a: #ffffff;
--theme-background-b: color-mix(in srgb, var(--theme-foreground) 4%, var(--theme-background-a));
--theme-background: var(--theme-background-a);
--theme-background-alt: var(--theme-background-b);
--theme-foreground-alt: color-mix(in srgb, var(--theme-foreground) 90%, var(--theme-background-a));
--theme-foreground-muted: color-mix(in srgb, var(--theme-foreground) 60%, var(--theme-background-a));
--theme-foreground-faint: color-mix(in srgb, var(--theme-foreground) 50%, var(--theme-background-a));
--theme-foreground-fainter: color-mix(in srgb, var(--theme-foreground) 30%, var(--theme-background-a));
--theme-foreground-faintest: color-mix(in srgb, var(--theme-foreground) 14%, var(--theme-background-a));
color-scheme: light;
}
.main-container {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
/* background: grey; */
padding: 1rem 0 1rem 0;
/* border: 0.1px solid black; */
}
.container {
position: relative;
width: fit-content;
height: fit-content;
display: flex;
align-items: center;
justify-content: center;
padding: 0rem;
border-radius: 0.75rem;
/* overflow: hidden; */
/* border: 0.1px solid black; */
}
.color1,
.color2,
.color3 {
position: absolute;
width: 100%;
height: 100%;
/* display: flex;
align-items: center;
justify-content: center; */
border-radius: 0.75rem;
z-index -55555;
}
.color1 {
top: -25%;
left: -30%;
}
.color1 path {
fill: #DD8A8A;
fill-opacity: 0.2;
}
.color2 {
top: 0;
right: 50%;
}
.color2 path {
fill: ##ECFF79;
fill-opacity: 0.3;
}
.color2 linearGradient stop:first-child {
stop-color: #FFE924;
}
.color2 linearGradient stop:last-child {
stop-color: #ECFF79;
stop-opacity: 0.32;
}
.color3 {
bottom: -20%;
/* background: radial-gradient(circle at center, #bb9ab1); */
}
.color3 path {
fill: ##ECFF79;
fill-opacity: 0.3;
}
.color3 linearGradient stop:first-child {
stop-color: #3EF3C8;
}
.color3 linearGradient stop:last-child {
stop-color: #3EF3C8;
stop-opacity: 0.5;
}
.card {
display: flex;
flex-direction: column;
gap: 1px;
align-items: center;
background: linear-gradient(to right, rgba(255, 255, 255, 0.1), rgba(230, 230, 230, 0.1), rgba(255, 255, 255, 0.1));
border: solid 1px var(--theme-foreground-faintest);
border-radius: 0.75rem;
padding: 1.5rem 1.5rem 1.5rem 1.5rem;
font: 1.5rem sans-serif;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); /* Added this line */
opacity: 1;
backdrop-filter: blur(1px);
z-index: 9999;
/* border: 0.1px solid black; */
}
.card > p{
width: 100%;
height: 100%;
/* padding: 0.5rem; */
/* border: 0.1px solid black; */
}
<style/>
5.5 Carbon monoxide (CO) emissions
<div class="main-container" style="">
<div class="container">
<svg class="color1" viewBox="0 0 465 408" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_11)">
<path d="M131.708 242.056C147.41 133.679 218.698 131.25 252.379 143.583C257.225 132.578 277.604 117.172 320.348 143.583C341.429 160.09 350.806 159.976 351.969 225.549C353.132 291.122 320.953 311.69 304.718 313.777H202.584C172.416 335.027 116.006 350.434 131.708 242.056Z" />
</g>
<defs>
<filter id="filter0_f_1_11" x="0" y="0" width="481" height="458" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="64.5" result="effect1_foregroundBlur_1_11" />
</filter>
</defs>
</svg>
<svg class="color2" viewBox="0 0 378 405" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_5)">
<path d="M215.096 264.863C231.993 207.121 162.183 120.603 220.473 144.628C278.763 168.652 325.84 241.568 308.943 299.309C292.045 357.051 217.573 377.753 159.283 353.729C100.993 329.704 198.198 322.604 215.096 264.863Z" fill="url(#paint0_linear_1_5)" />
</g>
<defs>
<filter id="filter0_f_1_5" x="0.866425" y="0.511726" width="451.556" height="503.05" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="70" result="effect1_foregroundBlur_1_5" />
</filter>
<linearGradient id="paint0_linear_1_5" x1="208.732" y1="374.109" x2="291.285" y2="173.813" gradientUnits="userSpaceOnUse">
<stop stop-color="" />
<stop offset="1" stop-color="" stop-opacity="" />
</linearGradient>
</defs>
</svg>
<svg class="color3" viewBox="0 0 423 518" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_4)">
<path d="M326.284 357.156C301.741 343.549 238.633 204.487 252.688 168.783C266.743 133.079 298.094 159.882 362.008 211.727C386.551 225.334 410.226 281.442 396.172 317.146C382.117 352.85 350.827 370.763 326.284 357.156Z" fill="url(#paint0_linear_1_4)"/>
</g>
<defs>
<filter id="filter0_f_1_4" x="0.670303" y="-97.5213" width="649.706" height="709.232" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="125" result="effect1_foregroundBlur_1_4"/>
</filter>
<linearGradient id="paint0_linear_1_4" x1="297.488" y1="320.285" x2="409.279" y2="303.653" gradientUnits="userSpaceOnUse">
<stop stop-color=""/>
<stop offset="1" stop-color="" stop-opacity=""/>
</linearGradient>
</defs>
</svg>
<div class="card" style="width:95%; height:100%; font-size:2rem;">
${(() => {
const data = airPollution.filter((d) =>
["United Kingdom", "United States", "India", "China", "World"].includes(
d.Entity
)
);
return Plot.plot({
marks: [
Plot.line(data, {
x: "Year",
y: "Carbon monoxide (CO) emissions",
z: "Entity",
stroke: "Entity",
tip: true
}),
Plot.ruleX(
data,
Plot.pointerX({
x: "Year",
py: "Carbon monoxide (CO) emissions",
z: "Entity",
stroke: "red"
})
),
Plot.dot(
data,
Plot.pointerX({
x: "Year",
y: "Carbon monoxide (CO) emissions",
z: "Entity",
stroke: "red"
})
),
Plot.text(
data,
Plot.selectLast({
x: "Year",
y: "Carbon monoxide (CO) emissions",
z: "Entity",
text: "Entity",
textAnchor: "start",
dx: -3,
dy: 9
})
)
],
y: {
type: "linear",
grid: true,
nice: true,
tickFormat: (d) => (d === 0 ? "0" : d / 1e6 + "M t"), // Format tick values in millions and append "t"
domain: d3.extent(data, (d) => d["Carbon monoxide (CO) emissions"]), // Set the maximum value
ticks: 8 // Set the number of ticks to 8, with a step of 20M
},
color: {
scheme: "spectral",
legend: true
},
title: "Carbon monoxide (CO) Trend",
width
});
})()}
</div>
</div>
</div>
Fixed the y axis range issue in Carbon monoxide (CO) emissions viz:
5.6 Carbon monoxide (CO) emissions Data viz reactive to pointer
viewof CO = Plot.plot({
marks: [
Plot.line(
airPollution.filter((d) =>
["United Kingdom", "United States", "India", "China", "World"].includes(
d.Entity
)
),
{
x: "Year",
y: "Carbon monoxide (CO) emissions",
z: "Entity",
stroke: "Entity",
tip: true
}
)
],
title: "Carbon monoxide (CO) emissions Data viz reactive to pointer"
})
Fixed the y axis range issue in Carbon monoxide (CO) emissions viz.
5.7 Organic carbon (OC) emissions
<div class="main-container" style="">
<div class="svg-container">
<svg class="svg1" viewBox="0 0 651 710" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_11_2)">
<path d="M326.28 455.153C301.737 441.546 238.629 302.484 252.684 266.78C266.739 231.076 298.09 257.878 362.004 309.723C386.547 323.33 410.222 379.439 396.167 415.143C382.113 450.847 350.823 468.76 326.28 455.153Z" fill="url(#paint0_linear_11_2)" />
</g>
<defs>
<filter id="filter0_f_11_2" x="0.665921" y="0.475006" width="649.706" height="709.232" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="100" result="effect1_foregroundBlur_11_2" />
</filter>
<linearGradient id="paint0_linear_11_2" x1="297.484" y1="418.282" x2="409.275" y2="401.649" gradientUnits="userSpaceOnUse">
<stop stop-color="#3EF3C8" />
<stop offset="1" stop-color="#3EF3C8" stop-opacity="0.5" />
</linearGradient>
</defs>
</svg>
<svg class="svg2" viewBox="0 0 465 408" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_11)">
<path d="M131.708 242.056C147.41 133.679 218.698 131.25 252.379 143.583C257.225 132.578 277.604 117.172 320.348 143.583C341.429 160.09 350.806 159.976 351.969 225.549C353.132 291.122 320.953 311.69 304.718 313.777H202.584C172.416 335.027 116.006 350.434 131.708 242.056Z" fill="#DD8A8A" fill-opacity="0.79" />
</g>
<defs>
<filter id="filter0_f_1_11" x="0" y="0" width="481" height="458" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="90" result="effect1_foregroundBlur_1_11" />
</filter>
</defs>
</svg>
<svg class="svg3" viewBox="0 0 428 459" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_9)">
<path d="M211.76 251.893C252.437 257.839 284.97 364.837 287.558 295.009C290.145 225.18 259.215 147.128 218.538 141.183C177.861 135.238 142.84 203.651 140.253 273.479C137.665 343.308 171.082 245.948 211.76 251.893Z" fill="url(#paint0_linear_1_9)" />
</g>
<defs>
<filter id="filter0_f_1_9" x="0.111717" y="0.821381" width="427.597" height="457.756" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="70" result="effect1_foregroundBlur_1_9" />
</filter>
<linearGradient id="paint0_linear_1_9" x1="142.448" y1="214.242" x2="290.347" y2="219.723" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFE924" />
<stop offset="1" stop-color="#ECFF79" stop-opacity="0.32" />
</linearGradient>
</defs>
</svg>
</div>
<div class="card" style="width:100%; height:100%; font-size:2rem;">
${(() => {
const data = airPollution.filter((d) =>
["United Kingdom", "United States", "India", "China", "World"].includes(
d.Entity
)
);
return Plot.plot({
marks: [
Plot.line(data, {
x: "Year",
y: "Organic carbon (OC) emissions",
z: "Entity",
stroke: "Entity",
tip: true
}),
Plot.ruleX(
data,
Plot.pointerX({
x: "Year",
py: "Organic carbon (OC) emissions",
z: "Entity",
stroke: "red"
})
),
Plot.dot(
data,
Plot.pointerX({
x: "Year",
y: "Organic carbon (OC) emissions",
z: "Entity",
stroke: "red"
})
),
Plot.text(
data,
Plot.selectLast({
x: "Year",
y: "Organic carbon (OC) emissions",
z: "Entity",
text: "Entity",
textAnchor: "start",
dx: -3,
dy: 9
})
)
],
y: {
type: "linear",
grid: true,
nice: true,
tickFormat: (d) => (d === 0 ? "0" : d / 1e6 + "M t"), // Format tick values in millions and append "t"
domain: d3.extent(data, (d) => d["Organic carbon (OC) emissions"]), // Set the maximum value
ticks: 8 // Set the number of ticks to 8, with a step of 20M
},
color: {
scheme: "spectral",
legend: true
},
title: "Organic carbon (OC) emissions Trend",
width
});
})()}
</div>
</div>
5.7 Non-methane volatile organic compounds (NMVOCs) emissions
<div class="main-container" style="">
<div class="card-svg-container" style="font-size:2rem;">
<div class="svg-container">
<svg class="svg1" viewBox="0 0 651 710" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_11_2)">
<path d="M326.28 455.153C301.737 441.546 238.629 302.484 252.684 266.78C266.739 231.076 298.09 257.878 362.004 309.723C386.547 323.33 410.222 379.439 396.167 415.143C382.113 450.847 350.823 468.76 326.28 455.153Z" fill="url(#paint0_linear_11_2)" />
</g>
<defs>
<filter id="filter0_f_11_2" x="0.665921" y="0.475006" width="649.706" height="709.232" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="100" result="effect1_foregroundBlur_11_2" />
</filter>
<linearGradient id="paint0_linear_11_2" x1="297.484" y1="418.282" x2="409.275" y2="401.649" gradientUnits="userSpaceOnUse">
<stop stop-color="#3EF3C8" />
<stop offset="1" stop-color="#3EF3C8" stop-opacity="0.5" />
</linearGradient>
</defs>
</svg>
<svg class="svg2" viewBox="0 0 428 459" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_9)">
<path d="M211.76 251.893C252.437 257.839 284.97 364.837 287.558 295.009C290.145 225.18 259.215 147.128 218.538 141.183C177.861 135.238 142.84 203.651 140.253 273.479C137.665 343.308 171.082 245.948 211.76 251.893Z" fill="url(#paint0_linear_1_9)" />
</g>
<defs>
<filter id="filter0_f_1_9" x="0.111717" y="0.821381" width="427.597" height="457.756" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="70" result="effect1_foregroundBlur_1_9" />
</filter>
<linearGradient id="paint0_linear_1_9" x1="142.448" y1="214.242" x2="290.347" y2="219.723" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFE924" />
<stop offset="1" stop-color="#ECFF79" stop-opacity="0.32" />
</linearGradient>
</defs>
</svg>
<svg class="svg3" viewBox="0 0 465 408" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_11)">
<path d="M131.708 242.056C147.41 133.679 218.698 131.25 252.379 143.583C257.225 132.578 277.604 117.172 320.348 143.583C341.429 160.09 350.806 159.976 351.969 225.549C353.132 291.122 320.953 311.69 304.718 313.777H202.584C172.416 335.027 116.006 350.434 131.708 242.056Z" fill="#DD8A8A" fill-opacity="0.79" />
</g>
<defs>
<filter id="filter0_f_1_11" x="0" y="0" width="481" height="458" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="90" result="effect1_foregroundBlur_1_11" />
</filter>
</defs>
</svg>
</div>
<div class="card" style="">
${(() => {
const data = airPollution.filter((d) =>
["United Kingdom", "United States", "India", "China", "World"].includes(
d.Entity
)
);
return Plot.plot({
marks: [
Plot.line(data, {
x: "Year",
y: "Non-methane volatile organic compounds (NMVOC) emissions",
z: "Entity",
stroke: "Entity",
tip: true
}),
Plot.ruleX(
data,
Plot.pointerX({
x: "Year",
py: "Non-methane volatile organic compounds (NMVOC) emissions",
z: "Entity",
stroke: "red"
})
),
Plot.dot(
data,
Plot.pointerX({
x: "Year",
y: "Non-methane volatile organic compounds (NMVOC) emissions",
z: "Entity",
stroke: "red"
})
),
Plot.text(
data,
Plot.selectLast({
x: "Year",
y: "Non-methane volatile organic compounds (NMVOC) emissions",
z: "Entity",
text: "Entity",
textAnchor: "start",
dx: -3,
dy: 9
})
)
],
y: {
type: "linear",
grid: true,
nice: true,
tickFormat: (d) => (d === 0 ? "0" : d / 1e6 + "M t"), // Format tick values in millions and append "t"
domain: d3.extent(data, (d) => d["Non-methane volatile organic compounds (NMVOC) emissions"]), // Set the maximum value
ticks: 8 // Set the number of ticks to 8, with a step of 20M
},
color: {
scheme: "spectral",
legend: true
},
title: "Non-methane volatile organic compounds (NMVOC) emissions Trend",
width
});
})()}
</div>
</div>
</div>
5.8 Black carbon (BC) emissions
<div class="main-container" style="">
<div class="card-svg-container" style="font-size:2rem;">
<div class="svg-container">
<svg class="svg1" viewBox="0 0 651 710" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_11_2)">
<path d="M326.28 455.153C301.737 441.546 238.629 302.484 252.684 266.78C266.739 231.076 298.09 257.878 362.004 309.723C386.547 323.33 410.222 379.439 396.167 415.143C382.113 450.847 350.823 468.76 326.28 455.153Z" fill="url(#paint0_linear_11_2)" />
</g>
<defs>
<filter id="filter0_f_11_2" x="0.665921" y="0.475006" width="649.706" height="709.232" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="100" result="effect1_foregroundBlur_11_2" />
</filter>
<linearGradient id="paint0_linear_11_2" x1="297.484" y1="418.282" x2="409.275" y2="401.649" gradientUnits="userSpaceOnUse">
<stop stop-color="#3EF3C8" />
<stop offset="1" stop-color="#3EF3C8" stop-opacity="0.5" />
</linearGradient>
</defs>
</svg>
<svg class="svg2" viewBox="0 0 428 459" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_9)">
<path d="M211.76 251.893C252.437 257.839 284.97 364.837 287.558 295.009C290.145 225.18 259.215 147.128 218.538 141.183C177.861 135.238 142.84 203.651 140.253 273.479C137.665 343.308 171.082 245.948 211.76 251.893Z" fill="url(#paint0_linear_1_9)" />
</g>
<defs>
<filter id="filter0_f_1_9" x="0.111717" y="0.821381" width="427.597" height="457.756" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="70" result="effect1_foregroundBlur_1_9" />
</filter>
<linearGradient id="paint0_linear_1_9" x1="142.448" y1="214.242" x2="290.347" y2="219.723" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFE924" />
<stop offset="1" stop-color="#ECFF79" stop-opacity="0.32" />
</linearGradient>
</defs>
</svg>
<svg class="svg3" viewBox="0 0 465 408" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_11)">
<path d="M131.708 242.056C147.41 133.679 218.698 131.25 252.379 143.583C257.225 132.578 277.604 117.172 320.348 143.583C341.429 160.09 350.806 159.976 351.969 225.549C353.132 291.122 320.953 311.69 304.718 313.777H202.584C172.416 335.027 116.006 350.434 131.708 242.056Z" fill="#DD8A8A" fill-opacity="0.79" />
</g>
<defs>
<filter id="filter0_f_1_11" x="0" y="0" width="481" height="458" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="90" result="effect1_foregroundBlur_1_11" />
</filter>
</defs>
</svg>
</div>
<div class="card" style="">
${(() => {
const data = airPollution.filter((d) =>
["United Kingdom", "United States", "India", "China", "World"].includes(
d.Entity
)
);
return Plot.plot({
marks: [
Plot.line(data, {
x: "Year",
y: "Black carbon (BC) emissions",
z: "Entity",
stroke: "Entity",
tip: true
}),
Plot.ruleX(
data,
Plot.pointerX({
x: "Year",
py: "Black carbon (BC) emissions",
z: "Entity",
stroke: "red"
})
),
Plot.dot(
data,
Plot.pointerX({
x: "Year",
y: "Black carbon (BC) emissions",
z: "Entity",
stroke: "red"
})
),
Plot.text(
data,
Plot.selectLast({
x: "Year",
y: "Black carbon (BC) emissions",
z: "Entity",
text: "Entity",
textAnchor: "start",
dx: -3,
dy: 9
})
)
],
y: {
type: "linear",
grid: true,
nice: true,
tickFormat: (d) => (d === 0 ? "0" : d / 1e6 + "M t"), // Format tick values in millions and append "t"
domain: d3.extent(data, (d) => d["Black carbon (BC) emissions"]), // Set the maximum value
ticks: 8 // Set the number of ticks to 8, with a step of 20M
},
color: {
scheme: "spectral",
legend: true
},
title: "Black carbon (BC) emissions Trend",
width
});
})()}
</div>
</div>
</div>
5.9 Ammonia (NH₃) emissions viz
<div class="main-container" style="">
<div class="card-svg-container" style="font-size:2rem;">
<div class="svg-container">
<svg class="svg1" viewBox="0 0 651 710" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_11_2)">
<path d="M326.28 455.153C301.737 441.546 238.629 302.484 252.684 266.78C266.739 231.076 298.09 257.878 362.004 309.723C386.547 323.33 410.222 379.439 396.167 415.143C382.113 450.847 350.823 468.76 326.28 455.153Z" fill="url(#paint0_linear_11_2)" />
</g>
<defs>
<filter id="filter0_f_11_2" x="0.665921" y="0.475006" width="649.706" height="709.232" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="100" result="effect1_foregroundBlur_11_2" />
</filter>
<linearGradient id="paint0_linear_11_2" x1="297.484" y1="418.282" x2="409.275" y2="401.649" gradientUnits="userSpaceOnUse">
<stop stop-color="#3EF3C8" />
<stop offset="1" stop-color="#3EF3C8" stop-opacity="0.5" />
</linearGradient>
</defs>
</svg>
<svg class="svg2" viewBox="0 0 428 459" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_9)">
<path d="M211.76 251.893C252.437 257.839 284.97 364.837 287.558 295.009C290.145 225.18 259.215 147.128 218.538 141.183C177.861 135.238 142.84 203.651 140.253 273.479C137.665 343.308 171.082 245.948 211.76 251.893Z" fill="url(#paint0_linear_1_9)" />
</g>
<defs>
<filter id="filter0_f_1_9" x="0.111717" y="0.821381" width="427.597" height="457.756" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="70" result="effect1_foregroundBlur_1_9" />
</filter>
<linearGradient id="paint0_linear_1_9" x1="142.448" y1="214.242" x2="290.347" y2="219.723" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFE924" />
<stop offset="1" stop-color="#ECFF79" stop-opacity="0.32" />
</linearGradient>
</defs>
</svg>
<svg class="svg3" viewBox="0 0 465 408" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_1_11)">
<path d="M131.708 242.056C147.41 133.679 218.698 131.25 252.379 143.583C257.225 132.578 277.604 117.172 320.348 143.583C341.429 160.09 350.806 159.976 351.969 225.549C353.132 291.122 320.953 311.69 304.718 313.777H202.584C172.416 335.027 116.006 350.434 131.708 242.056Z" fill="#DD8A8A" fill-opacity="0.79" />
</g>
<defs>
<filter id="filter0_f_1_11" x="0" y="0" width="481" height="458" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="90" result="effect1_foregroundBlur_1_11" />
</filter>
</defs>
</svg>
</div>
<div class="card" style="">
${(() => {
const data = airPollution.filter((d) =>
["United Kingdom", "United States", "India", "China", "World"].includes(
d.Entity
)
);
return Plot.plot({
marks: [
Plot.line(data, {
x: "Year",
y: "Ammonia (NH₃) emissions",
z: "Entity",
stroke: "Entity",
tip: true
}),
Plot.ruleX(
data,
Plot.pointerX({
x: "Year",
py: "Ammonia (NH₃) emissions",
z: "Entity",
stroke: "red"
})
),
Plot.dot(
data,
Plot.pointerX({
x: "Year",
y: "Ammonia (NH₃) emissions",
z: "Entity",
stroke: "red"
})
),
Plot.text(
data,
Plot.selectLast({
x: "Year",
y: "Ammonia (NH₃) emissions",
z: "Entity",
text: "Entity",
textAnchor: "start",
dx: -3,
dy: 9
})
)
],
y: {
type: "linear",
grid: true,
nice: true,
tickFormat: (d) => (d === 0 ? "0" : d / 1e6 + "M t"), // Format tick values in millions and append "t"
domain: d3.extent(data, (d) => d["Ammonia (NH₃) emissions"]), // Set the maximum value
ticks: 8 // Set the number of ticks to 8, with a step of 20M
},
color: {
scheme: "spectral",
legend: true
},
title: "Ammonia (NH₃) emissions Trend",
width
});
})()}
</div>
</div>
</div>
ObservableHq Notebook [Link]
Conclusion
Learning Objectives,
Data Ingestion
Data Transformation
Observable Notebook
Data Visualization
Filter data
Vertical ruler
Text at end of line
Visualization
Improved scale units.