You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Matplotlib中基于百分比累积计数实现栅格对比度增强?

Solution for Getting 2%/98% Percentiles for Raster vmin/vmax in Matplotlib

Hey there! I’ve dealt with this exact problem when building tools for aligned raster visualization, so let’s break down the steps to get you what you need:

1. First, Load Your Raster Data

You’ll need to read your single-band raster into a NumPy array (since Matplotlib plays seamlessly with NumPy, and we’ll use NumPy’s built-in functions for percentile calculations). I’ll use rasterio here (a go-to library for raster handling), but you can use other tools like gdal if you prefer:

import rasterio
import numpy as np
import matplotlib.pyplot as plt

# Load first raster
with rasterio.open("first_raster.tif") as src1:
    raster1 = src1.read(1)  # Read band 1
    nodata1 = src1.nodata

# Load second raster
with rasterio.open("second_raster.tif") as src2:
    raster2 = src2.read(1)
    nodata2 = src2.nodata

2. Filter Out NoData Values

Rasters almost always have invalid NoData pixels (like -9999), which will skew your percentile calculations if you leave them in. Let’s filter those out:

# Get valid pixels for each raster
valid_raster1 = raster1[raster1 != nodata1]
valid_raster2 = raster2[raster2 != nodata2]

3. Calculate Shared 2% and 98% Percentiles

Since you want matching color scales between the two images (so the same raster value maps to the same color), we’ll calculate percentiles across both datasets combined. If you wanted each image to use its own 2/98% range (but still aligned), you could calculate separately, but combining ensures a unified scale:

# Combine valid data from both rasters
combined_valid = np.concatenate([valid_raster1, valid_raster2])

# Compute 2nd and 98th percentiles
vmin = np.percentile(combined_valid, 2)
vmax = np.percentile(combined_valid, 98)

Note: np.percentile() is exactly the function you were missing! It calculates the value at the specified cumulative percentage of your dataset, just like QGIS’s cumulative count crop tool.

4. Plot the Images with Unified Scale

Now pass these vmin and vmax values to Matplotlib’s imshow() for both images, and add a shared colorbar to make alignment clear:

# Create side-by-side plot
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 7))

# Plot first raster with shared scale
im1 = ax1.imshow(raster1, vmin=vmin, vmax=vmax, cmap="viridis")
ax1.set_title("First Aligned Image")
ax1.axis("off")

# Plot second raster with the SAME scale
im2 = ax2.imshow(raster2, vmin=vmin, vmax=vmax, cmap="viridis")
ax2.set_title("Second Aligned Image")
ax2.axis("off")

# Add a single shared colorbar
fig.colorbar(im1, ax=[ax1, ax2], orientation="horizontal", pad=0.05, label="Raster Value")

plt.tight_layout()
plt.show()

Quick Notes

  • If you don’t want a shared scale (just each image using its own 2/98% range), skip combining the datasets and calculate vmin/vmax separately for each raster.
  • Double-check your NoData value: some rasters use np.nan instead of a numeric value, so you’d filter with ~np.isnan(raster_data) instead.

内容的提问来源于stack exchange,提问作者Jan-Pieter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 19:44:08