如何为display_bins()函数(基于pPXF数据)屏蔽异常数据?
问题描述
正在处理NGC 4684星系的速度和弥散数组,已通过pPXF获取全部数据,但存在一颗恒星导致运动学图出现明显偏差。希望完全屏蔽该异常数据区域,且保证处理后唯一bin与速度值一一匹配,避免出现数据不对应问题。
原始代码
# Make 1x2 sub plot fig, ax = plt.subplots(1,2,figsize=(10,10)) # # Start first plot - Velocity #============================ plt.subplot(121) # Subtract off the median (systemic) velocity, so that the rotation is around zero ax = display_bins(xpos, ypos, binNum, vpxf-numpy.median(vpxf), vmin=-160, vmax=160) # Set labels plt.title('Velocity') # Plot title plt.ylabel('Arcsec') # y-axis label plt.xlabel('Arcsec') # x-axis label # Plot colour bar cbar = plt.colorbar(ax, fraction=0.05, pad=0.04) cbar.ax.get_yaxis().labelpad = 15 cbar.ax.set_ylabel('km/s', rotation=270) #cbar.ax.set_clim(-200,200) #cbar = plt.colorbar(fig, fraction=0.05, pad=0.04, vmin=-200, vmax=200) #cbar.set_clim(-200, 200) # Set colorbar limits from 20 to 80 # # Start 2nd plot - Dispersion #============================ plt.subplot(122) # Call display_bins for the dispersion values ax = display_bins(xpos, ypos, binNum, spxf) # Insert code to overplot contours here: # Titles and colour bar plt.title('Dispersion') # y-axis label plt.ylabel('Arcsec') # y-axis label plt.xlabel('Arcsec') # x-axis label cbar = plt.colorbar(ax, fraction=0.05, pad=0.04) cbar.ax.get_yaxis().labelpad = 15 cbar.ax.set_ylabel('km/s', rotation=270) # Tweak the spacing fig.tight_layout(pad=2.5) # Show plots plt.show()
尝试的解决方案及问题
尝试代码
# Start first plot - Velocity #============================ plt.subplot(121) fixed_vel = [] fixed_binNum =[] fixed_xpos =[] fixed_ypos =[] for i in binNum: if vpxf[i]-numpy.median(vpxf) > -500: fixed_vel.append(vpxf[i]) fixed_binNum.append(binNum[i]) fixed_xpos.append(xpos[i]) fixed_ypos.append(ypos[i]) else: print(i, xpos[i],ypos[i],vpxf[i]) fixed_vel = numpy.unique(numpy.array(fixed_vel)) fixed_vel_med = fixed_vel - numpy.median(fixed_vel) fixed_binNum = numpy.array(fixed_binNum) fixed_xpos =numpy.array(fixed_ypos) fixed_ypos =numpy.array(fixed_xpos)
输出的异常数据
2 -20.8 12.0 -73.56390273059304 2 -20.8 12.0 -73.56390273059304 3 -20.8 12.8 -51.887747700703116 3 -20.8 12.8 -51.887747700703116 5 -20.8 14.4 -74.47643398005997 2 -20.8 12.0 -73.56390273059304 2 -20.8 12.0 -73.56390273059304 3 -20.8 12.8 -51.887747700703116 3 -20.8 12.8 -51.887747700703116 5 -20.8 14.4 -74.47643398005997 5 -20.8 14.4 -74.47643398005997 0 -21.6 14.4 -60.09910926725628 1 -21.6 15.2 -51.57607782626809 18 -19.2 8.8 -41.037816701653114 18 -19.2 8.8 -41.037816701653114 6 -20.8 15.2 -66.84680647265044 6 -20.8 15.2 -66.84680647265044 7 -20.0 9.6 -59.045807879638694 18 -19.2 8.8 -41.037816701653114 6 -20.8 15.2 -66.84680647265044 6 -20.8 15.2 -66.84680647265044 36 -18.4 11.2 -45.629206849673224 36 -18.4 11.2 -45.629206849673224 36 -18.4 11.2 -45.629206849673224
当前数据统计异常
==============original============== x 2045 y 2045 bin 2045 unique bin 293 vel 293 =============="fixed"============== x 2021 y 2021 bin 2021 unique bin 14 vel 284
处理后唯一bin数大幅减少,速度值与bin无法匹配,且binNum存在大量重复值。
正确解决方法
问题根源在于遍历逻辑错误(用bin ID作为数组索引)、过滤阈值设置错误,以及对速度值去重破坏了bin与速度的对应关系。以下是修正后的方案:
核心思路
- 基于原始绘图的
vmin=-160, vmax=160确定异常速度阈值 - 先标记所有速度超出阈值的bin
- 过滤掉属于异常bin的所有像素点,同时保留正常bin对应的速度值,保证一一对应
修正代码
import numpy as np # 计算系统中位速度 median_v = np.median(vpxf) # 设定与绘图一致的速度阈值 vel_low = -160 vel_high = 160 # 计算每个bin的速度(减去中位值后) vel_med = vpxf - median_v # 找出速度异常的bin索引 invalid_bin_indices = np.where((vel_med < vel_low) | (vel_med > vel_high))[0] # 过滤像素数据:保留不属于异常bin的像素 mask = ~np.isin(binNum, invalid_bin_indices) fixed_xpos = xpos[mask] fixed_ypos = ypos[mask] fixed_binNum = binNum[mask] # 过滤速度数据:保留正常bin的速度值 fixed_vpxf = vpxf[~np.isin(np.arange(len(vpxf)), invalid_bin_indices)] fixed_vel_med = fixed_vpxf - np.median(fixed_vpxf) # 若需保持原始系统中位值,可替换为median_v # 后续绘图使用过滤后的变量 plt.subplot(121) ax = display_bins(fixed_xpos, fixed_ypos, fixed_binNum, fixed_vel_med, vmin=vel_low, vmax=vel_high) # 其余绘图代码保持不变
关键说明
- 用
np.isin快速判断像素所属bin是否异常,避免循环遍历的低效与错误 - 不对速度值做去重,确保每个bin对应唯一的速度值
- 阈值与绘图时的
vmin/vmax保持一致,精准屏蔽异常区域
内容的提问来源于stack exchange,提问作者scrubster
相关产品推荐
相关产品推荐

