2015-01-26 54 views
1

我有兩個問題,在matplotlib等值線圖的最大值的位置:渲染非均勻網格,標誌着等值線圖

  1. 我怎樣才能使任意meshgrid作爲一個經常性的?

我希望兩個座標軸上刻度的位置均勻分佈,同時還能反映出我節點的位置。

  1. 如何使用彩色標記突出顯示數據最高值的位置?

enter image description here

這裏是我的代碼:

import numpy as np 
import pylab as pl 

def plot_s(data, xlist, ylist): 

    pl.subplot(111) 
    x = np.array(xlist) 
    y = np.array(ylist) 
    X, Y = np.meshgrid(x, y) 
    CS = pl.contour(X, Y, data, colors='k') 
    pl.clabel(CS, inline = 1, fontsize=10) 
    pl.xlabel('x list') 
    pl.ylabel('y list') 
    pl.xticks(xlist) 
    pl.yticks(ylist) 
    pl.title('Contour plot') 
    pl.show() 

def main(): 

    data = np.array([[ 0.56555019, 0.57933922, 0.58266252, 0.58067285, 0.57660236, 0.57185625, 0.56711252, 0.55557035, 0.55027705, 0.54480605], 
        [ 0.55486559, 0.57349717, 0.57940478, 0.57843897, 0.57463271, 0.56963449, 0.5643922 , 0.55095598, 0.54452534, 0.53762606], 
        [ 0.53529358, 0.56254991, 0.57328105, 0.57409218, 0.57066168, 0.5654082 , 0.55956853, 0.5432474 , 0.53501127, 0.52601203], 
        [ 0.50110483, 0.54004071, 0.55800178, 0.56173719, 0.55894846, 0.55328279, 0.54642887, 0.52598388, 0.51533094, 0.50354147]]) 

    xlist = [10., 20., 30., 40., 50., 60., 70., 100., 120., 150.] 
    ylist = [50, 70, 90, 100] 
    plot_s(data, xlist, ylist) 

if __name__ == '__main__': 
    main() 
+0

請注意,您不需要同時導入'pylab'和'numpy'。基本上'pylab'是'matplotlib'和'numpy'的簡便組合。在腳本中,最好分別導入兩個模塊以確保每個方法的來源。 import matplotlib.pyplot as plt import numpy as np – Julien 2015-02-03 20:59:12

回答

1
  1. 我怎樣才能使任意meshgrid作爲一個經常性的?

一個建議是創建一個規則的meshgrid,首先創建最小和最大x和y之間的均勻間隔值的數組。此外,您可以使用自定義滴答來反映您的數據點不是等距的事實。在代碼中查看關於我如何實現該功能的評論。

  1. 如何使用彩色標記突出顯示數據最高值的位置?

要檢索的最高值,你可以使用np.max(),然後找到該數據陣列np.where在這個值的位置。只需在此位置繪製一個標記。

另外,使用plt.contour你可以創建一個有足夠接近最高值的位置的水平輪廓,以在其上創建它周圍的環,或者甚至一個觀點:

epsillon = 0.0001 
levels = np.arange(max_value - epsillon, max_value + epsillon) 
CS2 = plt.contour(X,Y,data, levels, 
      origin='lower', 
      linewidths=2, 
      extent=(-3,3,-2,2)) 

注意,與第一方法中,點將在現有網格節點的頂部結束,而plt.contour會插值您的數據,並且根據所使用的插值算法,它可能會導致位置有所不同。然而在這裏它似乎同意。

的代碼:

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

def plot_s(data, x, y, xlist, ylist): 
    ax = plt.gca() 

    ########### create your uniform meshgrid..... ############ 
    X, Y = np.meshgrid(x, y) 
    CS = ax.contour(X, Y, data, colors='k') 

    ###### ... and let ticks indicate that your new space is not linear 
    # assign tick positions according to the regular array 
    ax.set_yticks(y) 
    # Assign the label to reflect your original nodes position 
    ax.set_yticklabels(ylist) 

    # and same for x 
    ax.set_xticks(x) 
    ax.set_xticklabels(xlist) 
    ############################################################# 


    ########### GET MAXIMUM AND MARK IT WITH A POINT ######## 
    # get maximum value in your data 
    max_value = np.max(data) 
    # get position index of this calue in your data array 
    local_max_index = np.where(data==max_value) 

    ## retrieve position of your 
    max_x = X[local_max_index[0], local_max_index[1]] 
    max_y = Y[local_max_index[0], local_max_index[1]] 

    # plot one marker on this position 
    plt.plot(max_x, max_y, color="red", marker = "o", zorder = 10, 
             markersize=15, clip_on=False) 
    ############################################################## 

    plt.title('Contour plot') 
    plt.show() 


def main(): 
    # Your data: 4 x 10 array 
    data = np.array([[ 0.56555019, 0.57933922, 0.58266252, 0.58067285, 0.57660236, 
         0.57185625, 0.56711252, 0.55557035, 0.55027705, 0.54480605], 
        [ 0.55486559, 0.57349717, 0.57940478, 0.57843897, 0.57463271, 
         0.56963449, 0.5643922 , 0.55095598, 0.54452534, 0.53762606], 
        [ 0.53529358, 0.56254991, 0.57328105, 0.57409218, 0.57066168, 
         0.5654082 , 0.55956853, 0.5432474 , 0.53501127, 0.52601203], 
        [ 0.50110483, 0.54004071, 0.55800178, 0.56173719, 0.55894846, 
         0.55328279, 0.54642887, 0.52598388, 0.51533094, 0.50354147]]) 
    # create a list values with regular interval for the mesh grid 
    x = np.array([10 + i * (150.-10.)/9 for i in range(10)]) 
    y = np.array([50 + i * (100.-50.)/4 for i in range(4)]) 

    # create arrays with values to be displayed as ticks  
    xlist = np.array([10., 20., 30., 40., 50., 60., 70., 100., 120., 150.]) 
    ylist = np.array([50, 70, 90, 100]) 

    plot_s(data, x, y, xlist, ylist) 

if __name__ == '__main__': 
    main() 

瞧:

在這裏,在後臺的meshgrid顯示變形/映射:

+1

實際上,可以通過'numpy.argmax()'(而不是'np.max()'和np.where ')。然而,這將返回索引在一個拉平(扁平)數組,所以需要使用'ymax,xmax = np.unravel_index(np.argmax(data),data.shape)'。 – Julien 2015-02-02 22:07:26

1

下面是essentiall y是相同的,但是snake_charmer提出的稍微更緊湊的版本。但是,我不確定我是否正確理解您的問題。如果你的積分xlistylist不是太不規則的間隔,更優雅的解決方案可能是保持不規則的網格,但使用ax.grid()突出顯示數據點的位置。這取決於你想要在圖中顯示的內容。

import numpy as np 
from matplotlib import pyplot as plt 

def plot_s(data, xlist, ylist): 

    fig, ax = plt.subplots() 
    x = np.arange(len(xlist)) 
    y = np.arange(len(ylist)) 
    X, Y = np.meshgrid(x, y) 
    CS = ax.contour(X, Y, data, colors='k') 
    ax.clabel(CS, inline = 1, fontsize=10) 
    ax.set_xlabel('x list') 
    ax.set_ylabel('y list') 
    ax.set_xticks(x) 
    ax.set_yticks(y) 
    ax.set_xticklabels(xlist) 
    ax.set_yticklabels(ylist) 

    jmax, imax = np.unravel_index(np.argmax(data), data.shape) 
    ax.plot(imax, jmax, 'ro') 

    ax.set_title('Contour plot') 
    plt.show() 

def main(): 

    data = np.array([[ 0.56555019, 0.57933922, 0.58266252, 0.58067285, 
         0.57660236, 0.57185625, 0.56711252, 0.55557035, 
         0.55027705, 0.54480605], 
        [ 0.55486559, 0.57349717, 0.57940478, 0.57843897, 
         0.57463271, 0.56963449, 0.5643922 , 0.55095598, 
         0.54452534, 0.53762606], 
        [ 0.53529358, 0.56254991, 0.57328105, 0.57409218, 
         0.57066168, 0.5654082 , 0.55956853, 0.5432474 , 
         0.53501127, 0.52601203], 
        [ 0.50110483, 0.54004071, 0.55800178, 0.56173719, 
         0.55894846, 0.55328279, 0.54642887, 0.52598388, 
         0.51533094, 0.50354147]]) 

    xlist = [10., 20., 30., 40., 50., 60., 70., 100., 120., 150.] 
    ylist = [50, 70, 90, 100] 
    plot_s(data, xlist, ylist) 

if __name__ == '__main__': 
    main()