Data Science project 07
Pollution Data Visualization Project in Python
Build a complete data visualization on pollution data workflow with reproducible Python code, traceable calculations, validation checks, and honest limitations.
Explore Data Science training in VizagView all project ideas
Analysis question
How can noisy daily measurements be converted into a readable, honest two-series trend chart?
Dataset
A 180-day synthetic series of PM2.5 and nitrogen-dioxide-like measurements in demonstration units.
Requirements
- Python 3.10 or later
- A terminal or command prompt
python -m pip install numpy pandas matplotlib- About 45-60 minutes to build and review
Method and data checks
Sort observations by date, calculate separate seven-day rolling averages, draw labelled lines with a shared axis, add a legend and grid, and save a high-resolution PNG.
- The title says the measurements are synthetic
- Units are labelled as demonstration units
- Both series use the same smoothing window
- The figure is closed after saving to avoid resource leaks
Complete Python code
Save the program as ds_pollution_visualization.py. The dataset generator or loader, analysis functions, output, and reproducibility controls are included.
"""Create a readable pollution trend chart from synthetic measurements."""
from __future__ import annotations
from pathlib import Path
import numpy as np
import pandas as pd
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
def make_demo_pollution(days: int = 180, seed: int = 42) -> pd.DataFrame:
rng = np.random.default_rng(seed)
dates = pd.date_range("2025-01-01", periods=days)
x = np.arange(days)
pm25 = np.clip(45 + 13 * np.sin(2 * np.pi * x / 30) + rng.normal(0, 7, days), 2, None)
no2 = np.clip(28 + 7 * np.sin(2 * np.pi * (x + 5) / 14) + rng.normal(0, 4, days), 1, None)
return pd.DataFrame({"date": dates, "pm25": pm25, "no2": no2})
def create_chart(data: pd.DataFrame, output: str | Path = "pollution_trends.png") -> Path:
plot = data.copy().sort_values("date")
plot["pm25_7d"] = plot["pm25"].rolling(7, min_periods=1).mean()
plot["no2_7d"] = plot["no2"].rolling(7, min_periods=1).mean()
fig, ax = plt.subplots(figsize=(10, 5.2))
ax.plot(plot["date"], plot["pm25_7d"], label="PM2.5, 7-day average", linewidth=2.2)
ax.plot(plot["date"], plot["no2_7d"], label="NOâ‚‚, 7-day average", linewidth=2.2)
ax.set(title="Synthetic pollution measurements", xlabel="Date", ylabel="Demo concentration units")
ax.grid(alpha=0.25)
ax.legend()
fig.tight_layout()
path = Path(output)
fig.savefig(path, dpi=150)
plt.close(fig)
return path
def main() -> None:
path = create_chart(make_demo_pollution())
print(f"Saved {path.resolve()}")
print("Synthetic teaching measurements — not a public-health data source.")
if __name__ == "__main__":
main()
Run the project
- Create and activate a virtual environment.
- Install dependencies with
python -m pip install numpy pandas matplotlib. - Run
python ds_pollution_visualization.py. - Reconcile row counts and totals before interpreting patterns.
- Read the limitations before substituting any real dataset.
Expected analytical output
A reviewable pollution_trends.png chart with two labelled seven-day-average lines.
Interpretation and responsible-use limits
The generated measurements and units are not environmental-monitoring evidence or public-health guidance. Real comparisons need calibrated sensors, comparable units, quality flags, and authoritative thresholds.
Ways to extend the project
Load an open government dataset, show missingness, add uncertainty bands, include a raw-data view, use accessible colours, and annotate documented events.
Continue learning Data Science
Try the next project, return to the Softenant project library, or explore the Data Science course in Vizag for guided data cleaning, analysis, visualisation, and portfolio feedback.