2D Histogram
Air Quality Index Distribution
Environmental monitoring showing PM2.5 concentration vs wind speed patterns for urban air quality.
Output
Python
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap
# Air quality data
np.random.seed(42)
n_readings = 9000
wind_speed = np.random.weibull(2.0, n_readings) * 8
wind_speed = np.clip(wind_speed, 0.5, 25)
base_pm25 = 150 / (1 + 0.3 * wind_speed)
pm25 = base_pm25 + np.random.exponential(15, n_readings)
pm25 = np.clip(pm25, 5, 300)
# Environmental theme
plt.style.use('dark_background')
fig, ax = plt.subplots(figsize=(10, 8))
fig.patch.set_facecolor('#081018')
ax.set_facecolor('#081018')
# Custom colormap - air quality green-blue
colors = ['#081018', '#0a2028', '#103038', '#184848', '#206058',
'#308068', '#40a078', '#60c088', '#80e098', '#a0f0a8', '#c0ffb8']
cmap = LinearSegmentedColormap.from_list('airquality', colors, N=256)
# 2D histogram
h = ax.hist2d(wind_speed, pm25, bins=50, cmap=cmap, cmin=1)
# AQI thresholds
ax.axhline(y=12, color='#60c088', linestyle='-', alpha=0.8, linewidth=2, label='Good (<12)')
ax.axhline(y=35.4, color='#ffa502', linestyle='--', alpha=0.7, linewidth=1.5, label='Moderate')
ax.axhline(y=55.4, color='#ff8c00', linestyle=':', alpha=0.7, linewidth=1.5, label='Unhealthy Sensitive')
ax.axhline(y=150.4, color='#ff6b6b', linestyle='--', alpha=0.7, linewidth=1.5, label='Unhealthy')
# Dispersion model
x_curve = np.linspace(0.5, 25, 100)
y_curve = 150 / (1 + 0.3 * x_curve)
ax.plot(x_curve, y_curve, '-', color='#a0f0a8', linewidth=2.5, alpha=0.8, label='Dispersion Model')
# Styled colorbar
cbar = plt.colorbar(h[3], ax=ax, pad=0.02, shrink=0.85)
cbar.ax.set_facecolor('#081018')
cbar.set_label('Reading Count', fontsize=11, color='#a0e0a8', labelpad=10)
cbar.ax.yaxis.set_tick_params(color='#a0e0a8')
cbar.outline.set_edgecolor('#205040')
plt.setp(plt.getp(cbar.ax.axes, 'yticklabels'), color='#a0e0a8', fontsize=9)
ax.set_xlabel('Wind Speed (m/s)', fontsize=13, color='#a0e0a8', fontweight='600', labelpad=10)
ax.set_ylabel('PM2.5 (ug/m3)', fontsize=13, color='#a0e0a8', fontweight='600', labelpad=10)
ax.set_title('Air Quality vs Wind Speed', fontsize=16, color='white', fontweight='bold', pad=20)
ax.tick_params(colors='#80c088', labelsize=10, length=0)
for spine in ax.spines.values():
spine.set_visible(False)
ax.legend(loc='upper right', fontsize=8, facecolor='#102028', edgecolor='#205040',
labelcolor='#a0e0a8', ncol=2)
plt.tight_layout()
plt.show()
Library
Matplotlib
Category
Statistical
More 2D Histogram examples
☕