2014-02-07 4 views
2

컨투어 플롯을 만들고 이미지의 윤곽을 오버레이해야합니다. 필자는 천체 이미지 위에 윤곽선을 덮기 위해 aplpy ​​라이브러리를 사용했습니다. 나는 APlpy 웹 사이트 (https://github.com/aplpy/aplpy-examples/tree/master/data)의 2MASS 데이터를 다운로드 한 다음 코드 조각을 썼다 :헤더를 사용하여 등고선 플롯 (matplotlib)을 FITS 형식으로 변환 할 수 있습니까?

import numpy as np 
import aplpy 
import atpy 
from pyavm import AVM 
import scipy 
import matplotlib.pyplot as plt 
import scipy.ndimage 
from matplotlib import cm 
import montage_wrapper 
import matplotlib.colors as colors 
from scipy import stats 

def get_contour_verts(cn): 
    contours = [] 
    # for each contour line 
    for cc in cn.collections: 
     paths = [] 
     # for each separate section of the contour line 
     for pp in cc.get_paths(): 
      xy = [] 
      # for each segment of that section 
      for vv in pp.iter_segments(): 
       xy.append(vv[0]) 
      paths.append(np.vstack(xy)) 
     contours.append(paths) 
    return contours 

# Convert all images to common projection 
aplpy.make_rgb_cube(['2MASS_h.fits', '2MASS_j.fits', '2MASS_k.fits'], '2MASS_rgb.fits') 

# Customize it 
aplpy.make_rgb_image('2MASS_rgb.fits','2MASS_rgb_contour.png',embed_avm_tags=True) 

# Launch APLpy figure of 2D cube 
img = aplpy.FITSFigure('2MASS_rgb_contour.png') 
img.show_rgb() 

# Modify the tick labels for precision and format 
img.tick_labels.set_xformat('hhmm') 
img.tick_labels.set_yformat('ddmm') 
# Move the tick labels 
img.tick_labels.set_xposition('top') 
img.tick_labels.set_yposition('right') 
img.tick_labels.set_font(size='small', family='sans-serif', style='normal') 

data = scipy.loadtxt('sources.txt') 
m1=data[:,0] 
m2=data[:,1] 
xmin = m1.min() 
xmax = m1.max() 
ymin = m2.min() 
ymax = m2.max() 
#Gridding the data 

X, Y = np.mgrid[xmin:xmax:100j, ymin:ymax:100j] 
positions = np.vstack([X.ravel(), Y.ravel()]) 
values = np.vstack([m1, m2]) 
kernel = stats.gaussian_kde(values) 
Z = np.reshape(kernel(positions).T, X.shape) 
fig = plt.figure() 
ax = fig.add_subplot(111) 
ax.imshow(np.rot90(Z), cmap=plt.cm.gist_earth_r, extent=[xmin, xmax, ymin, ymax]) 
ax.plot(m1, m2, 'k.', markersize=2) 
ax.set_xlim([xmin, xmax]) 
ax.set_ylim([ymin, ymax]) 

CS = plt.contour(X, Y, Z) 
Contour_arrays=get_contour_verts(CS) 

#Adding contour plots 
for contours_at_level in Contour_arrays: 
    radec = [img.pixel2world(*verts.T) for verts in contours_at_level] 
    new_radec=[] 
    for coor in radec: 
     #new_radec.append(np.column_stack((coor[0], coor[1]))) 
     new_radec.append(np.vstack((coor[0], coor[1]))) 
    print new_radec 
    img.show_lines(new_radec,color='red', zorder=100) 

img.save('tutorial.png') 

여전히 전혀 작동하지 않는 것입니다.

+0

Matplotlib을 사용하여 등고선 플롯을 만드는 방법에 관해서는 StackOverflow 주변에 많은 예제가 있습니다. 이제 플롯을 FITS 파일로 저장하려면 음모가있는 배열로 변환해야합니다 (예 : [여기] (http://www.icare.univ-lille1.fr/ wiki/index.php/How_to_convert_a_matplotlib_figure_to_a_numpy_array_or_a_PIL_image)), PyFITS를 사용하여 배열로 FITS 파일을 만듭니다. –

+0

@ RicardoCárdenes matplotlib 등고선 플롯을 배열로 변환 할 때 적경 및 편위 좌표에서 정보를 어떻게 전송할 수 있습니까? – Dalek

+0

@Dalek - 편집 한 루프와 일치하도록 루프를 변경하십시오. 나는 실수를 저질렀다. 당신이 만든 등고선은 ra/dec 좌표에서 * 이미 *이므로 픽셀 -> 월드 변환을 할 필요가 없습니다. 링크 된 예제 (github.com/aplpy/aplpy-examples/pull/1)에는 정확한 버전 – keflavich

답변

2

"윤곽을 FITS 파일로 저장"할 수는 없지만 시도 할 수있는 다른 방법이 있습니다.

Python: find contour lines from matplotlib.pyplot.contour()과 같이 matplotlib._cntr 도구를 사용하여 그림 좌표의 끝점을 얻은 다음 WCS를 사용하여 픽셀 좌표와 세계 좌표를 변환 할 수 있습니다. , 당신이 당신의 포인트를 변환 할 수 있습니다 당신이 FITSFigure 창에 표시된 것과 동일 인 격자로 작업하는 경우 그래서

F.pixel2world(arange(5),arange(5)) 

: aplpy.FITSFigure들 각각이 개 배열을 받아 편의 기능, F.world2pixelF.pixel2world을 가지고 세계와 show_lines로 음모 좌표 :

ra,dec = F.pixel2world(xpix,ypix) 
F.show_lines([[ra,dec]]) 

또는 지금 링크 된 기사에서 코드를 복사 해보다 현실적인 윤곽 케이스에 대한

:

,536,
import numpy as np 
import aplpy 

def get_contour_verts(cn): 
    contours = [] 
    # for each contour line 
    for cc in cn.collections: 
     paths = [] 
     # for each separate section of the contour line 
     for pp in cc.get_paths(): 
      xy = [] 
      # for each segment of that section 
      for vv in pp.iter_segments(): 
       xy.append(vv[0]) 
      paths.append(np.vstack(xy)) 
     contours.append(paths) 

    return contours 

# This line is copied from the question's code, and assumes that has been run previously 
CS = plt.contour(Xgrid, Ygrid, Hsmooth,levels=loglvl,extent=extent,norm=LogNorm()) 

contours = get_contour_verts(CS) # use the linked code 


gc = aplpy.FITSFigure('2MASS.fits',figsize=(10,9)) 

# each level comes with a different set of vertices, so you have to loop over them 
for contours_at_level in Contour_arrays: 
    clines = [cl.T for cl in contours_at_level] 
    img.show_lines(clines,color='red', zorder=100) 

여전히 가장 간단한 방법은 상기 등고선을 생성하는 FITS 파일이있는 경우 해당 파일을 직접 사용하는 것입니다. 또는 FITS 파일이 없으면 자신 만의 머리글을 만들어 불우한 것들로 만들 수 있습니다.

+0

이 있습니다. 윤곽선에서 그리드 된 데이터를 변환하기 위해 WCS (astropy에서 사용)를 사용하는 방법을 자세히 설명해 주시겠습니까? WCS에 줄거리? – Dalek

+0

Dalek : 상세한 대답은 – keflavich

+0

을 추가했습니다. 나는 그것을 구현해야하는 방법으로 아직도 매우 모호합니다. 내가 c = cntr.Cntr (Xgrid, Ygrid, Hsmooth)을 사용한다면 c.get_cdata()는 나에게 (nx, ny) 배열을 주지만 각 격자 점의 양과 다른 한편으로는 c.trace (z) ra와 dec 좌표에있는 등고선의 점 목록. 어떤 파일을 fit 파일로 변환해야하는지, 그리고 어느 파일을 aplpy.FITSFigure()에서 show_contour()로 읽을 수 있는지 조금 더 설명 할 수 있습니까? 감사합니다. – Dalek