簡體   English   中英

Matplotlib pcolor

[英]Matplotlib pcolor

我正在使用Matplotlib根據一些數據創建圖像。 所有數據都在0到1的范圍內,我試圖使用色彩圖基於其值對數據進行着色,這在Matlab中完美運行,但是當將代碼轉換為Python時,我只需得到一個黑色正方形輸出。 我相信這是因為我正在繪制錯誤的圖像,所以它將所有數據繪制為0.我已經嘗試了幾個小時搜索這個問題而且我已經嘗試了plt.set_clim([0, 1])但是那並沒有好像什么都做。 我是Python和Matplotlib的新手,雖然我不是編程新手(Java,javascript,PHP等),但我看不出我哪里出錯了。 如果任何身體在我的代碼中可以看到任何明顯不正確的內容,那么我將非常感激。

謝謝

from numpy import *
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.colors as myColor

e1cx=[]
e1cy=[]
e1cz=[]
print("Reading files...")
in_file = open("eigenvector_1_component_x.txt", "rt")
for line in in_file.readlines():
e1cx.append([])
for i in line.split():
    e1cx[-1].append(float(i))
in_file.close()
in_file = open("eigenvector_1_component_y.txt", "rt")
for line in in_file.readlines():
e1cy.append([])
for i in line.split():
    e1cy[-1].append(float(i))
in_file.close()
in_file = open("eigenvector_1_component_z.txt", "rt")
for line in in_file.readlines():
e1cz.append([])
for i in line.split():
    e1cz[-1].append(float(i))
in_file.close()
print("...done")

nx = 120
ny = 128
nz = 190


fx = zeros((nz,nx,ny))
fy = zeros((nz,nx,ny))
fz = zeros((nz,nx,ny))

z = 0
while z<nz-1:
x = 0
while x<nx:
    y = 0
    while y<ny:
        fx[z][x][y]=e1cx[(z*128)+y][x]
        fy[z][x][y]=e1cy[(z*128)+y][x]
        fz[z][x][y]=e1cz[(z*128)+y][x]
        y += 1
    x += 1
z+=1
if((z % 10) == 0):      
    plt.figure(num=None)
    plt.axis("off")
    normals = myColor.Normalize(vmin=0,vmax=1)
    plt.pcolor(fx[z][:][:],cmap='spectral', norm=normals)   
    filename = 'Imagex_%d' % z
    plt.savefig(filename)
    plt.colorbar(ticks=[0,2,4,6], format='%0.2f')

雖然你已經解決了原始問題並且代碼有效,但我想指出python和numpy都提供了一些工具,使得這樣的代碼編寫起來更加簡單。 這里有一些例子:

加載數據中

不是通過附加到空列表的末尾來構建列表,而是通過其他列表生成列表通常更容易。 例如,而不是

e1cx = []
for line in in_file.readlines():
  e1cx.append([])
  for i in line.split():
    e1cx[-1].append(float(i))

你可以簡單地寫:

e1cx = [[float(i) for i in line.split()] for line in in_file]

語法[x(y) for y in l]被稱為列表推導 ,並且除了更簡潔之外,它將比for循環更快地執行。

但是,要從文本文件加載表格數據,使用numpy.loadtxt更簡單:

import numpy as np
e1cx = np.loadtxt("eigenvector_1_component_x.txt")

欲獲得更多信息,

print np.loadtxt.__doc__

另見,其稍微復雜的堂兄numpy.genfromtxt

重塑數據

現在我們已經加載了數據,我們需要重塑它。 你使用的while循環工作正常,但numpy提供了一種更簡單的方法。 首先,如果您更喜歡使用加載數據的方法,那么使用e1cx = array(e1cx)等將您的特征向量數組轉換為適當的numpy數組。

array類提供了重新排列數組中數據索引的方法,而無需復制它。 最簡單的方法是array.reshape ,它將執行while循環的一半:

almost_fx = e1cx.reshape((nz,ny,nx))

這里, almost_fx是一個rank-3數組,索引為almost_fx[iz,iy,ix] 需要注意的一件重要事情是e1cxalmost_fx共享他們的數據。 因此,如果更改e1cx[0,0] ,您還將更改almost_fx[0,0,0]

在您的代碼中,您交換了x和y位置。 如果這確實是你想要做的,你可以使用array.swapaxes完成這個:

fx = almost_fx.swapaxes(1,2)

當然,您總是可以將它組合成一行

fx = e1cx.reshape((nz,ny,nx)).swapaxes(1,2)

但是,如果您希望z切片( fx[z,:,:]以x水平和y垂直繪圖,您可能不希望交換上面的軸。 只是重塑和策划。

切片陣列

最后,不是循環遍歷z-index並測試10的倍數,而是可以使用以下方法直接在數組的一個切片上循環:

for fx_slice in fx[::10]:
  # plot fx_slice and save it 

這個索引語法是array[start:end:step]其中, start被包括在結果end是沒有的。 start空白表示為0,而將end空白表示列表的結尾。

摘要

總之,您的完整代碼(在介紹了一些像enumerate這樣的python習語之后)可能看起來像:

import numpy as np
from matplotlib import pyplot as pt

shape = (190,128,120)

fx = np.loadtxt("eigenvectors_1_component_x.txt").reshape(shape).swapaxes(1,2)

for i,fx_slice in enumerate(fx[::10]):
  z = i*10
  pt.figure()
  pt.axis("off")
  pt.pcolor(fx_slice, cmap='spectral', vmin=0, vmax=1)
  pt.colorbar(ticks=[0,2,4,6], format='%0.2f')
  pt.savefig('Imagex_%d' % z)

或者,如果每個元素需要一個像素,則可以用for替換for循環體

z = i*10
pt.imsave('Imagex_%d' % z, fx_slice, cmap='spectral', vmin=0, vmax=1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM