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

如何将含光谱信息的XY坐标映射数据转换为字典(或替代结构)并实现光谱高斯拟合与振幅可视化?

Hey there! Let's tackle this problem step by step. Here's a comprehensive solution tailored to your needs, including data transformation, Gaussian fitting, and visualization:

1. Data Transformation: Dictionary or Numpy Array

You've already got the pandas import down—great start! Let's convert that tabular data into structures that scale well for 400+ pixels and 512-wave spectra.

Option 1: Dictionary of (X,Y) Tuples to Numpy Arrays

This matches the structure you requested, and it automatically handles any number of pixels/spectrum lengths:

import pandas as pd
import numpy as np

# Your existing data import code
IN_PATH = r'PATH_TO_FILE'
FNAME = r'\FILENAME.txt'
data = pd.read_csv(IN_PATH + FNAME, sep='\t', skiprows=1)
data.columns = ["X", "Y", "Wave", "Intensity"]

# Build the spectrum dictionary
spectrum_dict = {}
for (x, y), group in data.groupby(['X', 'Y']):
    # Convert each group's Wave/Intensity pairs to a 2D numpy array
    spectrum = group[['Wave', 'Intensity']].to_numpy()
    spectrum_dict[(x, y)] = spectrum

This will capture every unique (X,Y) coordinate and store its full spectrum as a (n,2) array (where n=512 for your real data).

Numpy arrays are faster for numerical operations like fitting, and they simplify plotting. Here's how to create a grid-aligned array:

# Get sorted unique coordinates to form a grid
unique_x = np.sort(data['X'].unique())
unique_y = np.sort(data['Y'].unique())
num_x, num_y = len(unique_x), len(unique_y)
spectrum_length = 512  # Use len(group) if your spectrum lengths vary (though you said they're fixed)

# Map coordinates to array indices
x_to_idx = {x: i for i, x in enumerate(unique_x)}
y_to_idx = {y: j for j, y in enumerate(unique_y)}

# Initialize empty array (shape: [Y rows, X columns, spectrum length, 2 (Wave/Intensity)])
spectrum_array = np.zeros((num_y, num_x, spectrum_length, 2), dtype=np.float64)

# Fill the array with spectrum data
for (x, y), group in data.groupby(['X', 'Y']):
    i = x_to_idx[x]
    j = y_to_idx[y]
    spectrum_array[j, i] = group[['Wave', 'Intensity']].to_numpy()
2. Gaussian Fitting for Maximum Amplitude

Next, let's fit each spectrum to a Gaussian distribution and extract the peak amplitude. We'll use scipy.optimize.curve_fit for this:

First, define the Gaussian function:

from scipy.optimize import curve_fit

def gaussian(x, amp, mean, std):
    """Gaussian function: amplitude, mean (center), standard deviation"""
    return amp * np.exp(-(x - mean)**2 / (2 * std**2))

Fitting with the Dictionary Approach

amplitude_dict = {}
for (x, y), spectrum in spectrum_dict.items():
    wave = spectrum[:, 0]
    intensity = spectrum[:, 1]
    
    # Initial guess for fitting (max intensity, mid-wave value, rough spread)
    initial_guess = [np.max(intensity), np.mean(wave), np.std(wave)]
    
    try:
        # Fit the Gaussian to the data
        popt, _ = curve_fit(gaussian, wave, intensity, p0=initial_guess)
        amplitude_dict[(x, y)] = popt[0]  # Store the amplitude parameter
    except RuntimeError:
        # Handle cases where fitting fails (e.g., noisy spectra)
        amplitude_dict[(x, y)] = np.nan

Fitting with the Numpy Array Approach

This is more efficient for large datasets:

amplitude_array = np.full((num_y, num_x), np.nan)

for j in range(num_y):
    for i in range(num_x):
        spectrum = spectrum_array[j, i]
        wave = spectrum[:, 0]
        intensity = spectrum[:, 1]
        
        initial_guess = [np.max(intensity), np.mean(wave), np.std(wave)]
        
        try:
            popt, _ = curve_fit(gaussian, wave, intensity, p0=initial_guess)
            amplitude_array[j, i] = popt[0]
        except RuntimeError:
            amplitude_array[j, i] = np.nan
3. Visualize the Amplitude Map

Finally, plot the maximum amplitude for each (X,Y) coordinate using matplotlib:

For the Numpy Array Approach (Simpler)

import matplotlib.pyplot as plt

plt.figure(figsize=(10, 8))
# Use actual X/Y values for accurate axis labels
plt.pcolormesh(unique_x, unique_y, amplitude_array, cmap='viridis')
plt.colorbar(label='Gaussian Peak Amplitude')
plt.xlabel('X Coordinate')
plt.ylabel('Y Coordinate')
plt.title('2D Map of Spectrum Gaussian Amplitudes')
plt.show()

For the Dictionary Approach

First reshape the data into a grid, then plot:

# Extract coordinates and amplitudes
xs, ys = zip(*amplitude_dict.keys())
amps = list(amplitude_dict.values())

# Reshape into grid (assuming your coordinates form a regular grid)
xs = np.array(xs).reshape(num_y, num_x)
ys = np.array(ys).reshape(num_y, num_x)
amps = np.array(amps).reshape(num_y, num_x)

plt.figure(figsize=(10, 8))
plt.pcolormesh(xs, ys, amps, cmap='viridis')
plt.colorbar(label='Gaussian Peak Amplitude')
plt.xlabel('X Coordinate')
plt.ylabel('Y Coordinate')
plt.title('2D Map of Spectrum Gaussian Amplitudes')
plt.show()

Notes for Scaling

  • The numpy array approach is better for 400+ pixels—it's faster for fitting and plotting.
  • Add more error handling if needed (e.g., checking for NaN values in spectra before fitting).
  • If your spectra have multiple peaks, you can modify the Gaussian function to a multi-peak version (e.g., sum of 2-3 Gaussians) and adjust the initial guess accordingly.

内容的提问来源于stack exchange,提问作者T Walker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 05:27:35