[英]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]
。 需要注意的一件重要事情是e1cx
和almost_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.