Solution and implementation for Q11 from Data Modeling & Visualization (dmv).
Problem Statement: Analyzing Air Quality Index (AQI) Trends in a City
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
air = pd.read_csv("City_Air_Quality.csv", parse_dates=["Date"])
print("Shape:", air.shape)
print(air.head().to_string(index=False))
print(air[["PM2.5", "PM10", "CO", "AQI"]].describe().round(2).to_string())
# Overall AQI time series and individual pollutant trends.
fig, axes = plt.subplots(3, 1, figsize=(11, 9))
air.plot(x="Date", y="AQI", ax=axes[0], legend=False, color="firebrick", title="AQI over time")
air.plot(x="Date", y=["PM2.5", "PM10"], ax=axes[1], title="Particulate matter over time")
air.plot(x="Date", y="CO", ax=axes[2], legend=False, color="teal", title="CO over time")
axes[0].set_ylabel("AQI")
axes[1].set_ylabel("µg/m³")
axes[2].set_ylabel("CO")
plt.tight_layout()
plt.show()
# Compare monthly AQI and AQI distributions across PM2.5 categories.
air["Month"] = air["Date"].dt.to_period("M").astype(str)
fig, axes = plt.subplots(1, 2, figsize=(11, 4))
air.groupby("Month")["AQI"].mean().plot.bar(ax=axes[0], color="slateblue", title="Mean AQI by month")
axes[0].set_ylabel("Mean AQI")
axes[0].tick_params(axis="x", rotation=45)
air["PM25Band"] = pd.cut(air["PM2.5"], bins=[0, 25, 40, 60, np.inf], labels=["Low", "Moderate", "High", "Very high"])
bands = [(label, air.loc[air["PM25Band"] == label, "AQI"]) for label in air["PM25Band"].cat.categories]
bands = [(label, values) for label, values in bands if not values.empty]
axes[1].boxplot([values for _, values in bands], tick_labels=[label for label, _ in bands])
axes[1].set_title("AQI by PM2.5 category")
axes[1].set_ylabel("AQI")
plt.tight_layout()
plt.show()
# Explore the relationship between particulate matter and AQI.
fig, axes = plt.subplots(1, 2, figsize=(11, 4))
axes[0].scatter(air["PM2.5"], air["AQI"], c=air["CO"], cmap="viridis", alpha=0.7)
axes[0].set(xlabel="PM2.5", ylabel="AQI", title="AQI versus PM2.5 (color = CO)")
correlation = air[["PM2.5", "PM10", "CO", "AQI"]].corr()
image = axes[1].imshow(correlation, cmap="coolwarm", vmin=-1, vmax=1)
axes[1].set_xticks(range(4), correlation.columns, rotation=35)
axes[1].set_yticks(range(4), correlation.columns)
axes[1].set_title("Measurement correlations")
fig.colorbar(image, ax=axes[1], shrink=0.8)
plt.tight_layout()
plt.show()