2013-04-24 24 views
11

我有一個座標變換的2d圖。每個點處的數據都是原始座標系統中的假定角度,從0到360.我試圖用pyplot.contour來繪製等角度的線條,例如45度。輪廓出現在兩個極點之間的45度線上,但是沿着0/360不連續點連接兩個極點的輪廓還有一個附加部分。這使得一條非常鋸齒的醜陋線條,因爲它基本上只是跟蹤一個數字接近0的像素,另一個接近360的像素。停止從不連續點繪製輪廓的pyplot.contour

例子: 下面是一個使用全綵色地圖圖像: colour map with discontinuity

你可以看到沿着左側的藍色/紅色曲線的不連續性。一面是360度,另一面是0度。當繪製的輪廓,我得到:

contour plot with discontinuity

注意,所有的輪廓連接兩極,但即使我沒有繪製0度輪廓,所有其它輪廓沿0度不連續性跟蹤(因爲pyplot認爲一方是0,另一方是360,兩者之間必須有所有其他角度)。

代碼產生這樣的數據:

import numpy as np 
import matplotlib.pyplot as plt 
jgal = np.array([[-0.054875539726,-0.873437108010,-0.483834985808],\ 
       [0.494109453312,-0.444829589425, 0.746982251810],\ 
       [-0.867666135858,-0.198076386122, 0.455983795705]]) 

def s2v3(rra, rdec, r): 
    pos0 = r * np.cos(rra) * np.cos(rdec) 
    pos1 = r * np.sin(rra) * np.cos(rdec) 
    pos2 = r * np.sin(rdec) 
    return np.array([pos0, pos1, pos2]) 

def v2s3(pos): 
    x = pos[0] 
    y = pos[1] 
    z = pos[2] 
    if np.isscalar(x): x, y, z = np.array([x]), np.array([y]), np.array([z]) 
    rra = np.arctan2(y, x) 
    low = np.where(rra < 0.0) 
    high = np.where(rra > 2.0 * np.pi) 
    if len(low[0]): rra[low] = rra[low] + (2.0*np.pi) 
    if len(high[0]): rra[high] = rra[high] - (2.0*np.pi) 
    rxy = np.sqrt(x**2 + y**2) 
    rdec = np.arctan2(z, rxy) 
    r = np.sqrt(x**2 + y**2 + z**2) 
    if x.size == 1: 
     rra = rra[0] 
     rdec = rdec[0] 
     r = r[0] 
    return rra, rdec, r 


def gal2fk5(gl, gb): 
    dgl = np.array(gl) 
    dgb = np.array(gb) 
    rgl = np.deg2rad(gl) 
    rgb = np.deg2rad(gb) 
    r = 1.0 
    pos = s2v3(rgl, rgb, r) 

    pos1 = np.dot(pos.transpose(), jgal).transpose() 

    rra, rdec, r = v2s3(pos1) 

    dra = np.rad2deg(rra) 
    ddec = np.rad2deg(rdec) 

    return dra, ddec 


def make_coords(resolution=50): 
    width=9 
    height=6 
    px = width*resolution 
    py = height*resolution 
    coords = np.zeros((px,py,4)) 
    for ix in range(0,px): 
     for iy in range(0,py): 
      l = 360.0/px*ix - 180.0 
      b = 180.0/py*iy - 90.0 
      dra, ddec = gal2fk5(l,b) 
      coords[ix,iy,0] = dra 
      coords[ix,iy,1] = ddec 
      coords[ix,iy,2] = l 
      coords[ix,iy,3] = b 
    return coords 

coords = make_coords() 

# now do one of these 
#plt.imshow(coords[:,:,0],origin='lower') # color plot 
#plt.contour(coords[:,:,0],levels=[45,90,135,180,225,270,315]) # contour plot with jagged ugliness 

我怎樣才能既:從圖紙輪廓沿間斷

  • 化妝

    1. 停止pyplot.contour pyplot.contour認識0/360角度的不連續性根本不是真正的不連續性。

    我就可以提高基礎數據的分辨率,但在此之前我得到一個不錯的流暢的線條,它開始需要很長的時間和大量的內存情節。

    我也想繪製一個沿0度的輪廓,但是如果我能弄清楚如何隱藏不連續性,我可以將它移到其他不在輪廓附近的地方。或者,如果我能讓#2發生,這不會是一個問題。

  • +2

    如果您可以發佈問題圖的圖像,或者生成(簡化)版本的示例代碼,這將有所幫助。 – askewchan 2013-04-25 01:31:15

    +0

    我剛剛添加了示例圖來說明問題 – GJP 2013-04-26 13:23:55

    +1

    這是輪廓的一種奇怪的用法,我不認爲您將能夠按照自己的方式使其工作。不過,我相信你可以用輪廓以外的東西來得到你想要的情節。使用'imshow'會給你一些東西,比如你的頂部情節,'streamplot'會給你一些接近你的底部情節的東西。哪個情節更接近你最終想要的?你能提供一個產生數據字段的函數,所以我們有一些東西可以玩嗎? – Paul 2013-04-26 18:23:29

    回答

    1

    這無疑仍是一個黑客,但你可以得到很好的平滑的輪廓具有雙重方法:

    1. 相位的絕對值的情節輪廓(打算從-180˚到180˚)所以沒有不連續性。
    2. 情節兩個有限區域集合的輪廓,使靠近頂部和極值的底部數值缺陷不蠕變

    下面是完整的代碼添加到您的示例:

    Z = np.exp(1j*np.pi*coords[:,:,0]/180.0) 
    Z *= np.exp(0.25j*np.pi/2.0) # Shift to get same contours as in your example 
    X = np.arange(300) 
    Y = np.arange(450) 
    
    N = 2 
    levels = 90*(0.5 + (np.arange(N) + 0.5)/N) 
    c1 = plt.contour(X, Y, abs(np.angle(Z)*180/np.pi), levels=levels) 
    c2 = plt.contour(X, Y, abs(np.angle(Z*np.exp(0.5j*np.pi))*180/np.pi), levels=levels) 
    

    Smooth contour plot of phase angle

    一個可以概括這個代碼來獲得平滑的輪廓爲任何「週期性」的功能。剩下要做的是用正確的值生成一組新的等值線,這樣colormap正確應用,標籤將被正確應用等等。但是,似乎沒有一種簡單的方式使用matplotlib來做到這一點:相關的QuadContourSet課程完成所有工作,我沒有看到從輪廓c1c2構建適當輪廓對象的簡單方法。