Matplotlib pcolor

jbm*_*991 3 python matplotlib

我正在使用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')
Run Code Online (Sandbox Code Playgroud)

小智 7

虽然你已经解决了你的原始问题并且代码有效,但我想指出python和numpy都提供了一些工具,使得编写这样的代码变得更加简单.这里有一些例子:

加载数据中

不是通过附加到空列表的末尾来构建列表,而是通过其他列表生成列表通常更容易.例如,而不是

e1cx = []
for line in in_file.readlines():
  e1cx.append([])
  for i in line.split():
    e1cx[-1].append(float(i))
Run Code Online (Sandbox Code Playgroud)

你可以简单地写:

e1cx = [[float(i) for i in line.split()] for line in in_file]
Run Code Online (Sandbox Code Playgroud)

语法[x(y) for y in l]被称为列表推导,并且除了更简洁之外,它将比for循环更快地执行.

但是,要从文本文件加载表格数据,使用起来更简单numpy.loadtxt:

import numpy as np
e1cx = np.loadtxt("eigenvector_1_component_x.txt")
Run Code Online (Sandbox Code Playgroud)

欲获得更多信息,

print np.loadtxt.__doc__
Run Code Online (Sandbox Code Playgroud)

另见,它的表亲略显复杂 numpy.genfromtxt

重塑数据

现在我们已经加载了数据,我们需要对其进行重塑.你使用的while循环工作正常,但numpy提供了一种更简单的方法.首先,如果您更喜欢使用加载数据的方法,那么使用e1cx = array(e1cx)等将您的特征向量数组转换为适当的numpy数组.

array类提供用于重排如何在一个阵列中的数据,而不需要将其复制索引方法.最简单的方法是array.reshape,它将执行while循环的一半:

almost_fx = e1cx.reshape((nz,ny,nx))
Run Code Online (Sandbox Code Playgroud)

这里almost_fx是一个索引为3的秩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)
Run Code Online (Sandbox Code Playgroud)

当然,您总是可以将它组合成一行

fx = e1cx.reshape((nz,ny,nx)).swapaxes(1,2)
Run Code Online (Sandbox Code Playgroud)

但是,如果您希望z-slices(fx[z,:,:])以x水平和y垂直绘图,您可能不希望交换上面的轴.只是重塑和策划.

切片阵列

最后,不是循环遍历z-index并测试10的倍数,而是可以使用以下方法直接在数组的一个切片上循环:

for fx_slice in fx[::10]:
  # plot fx_slice and save it 
Run Code Online (Sandbox Code Playgroud)

这索引语法array[start:end:step],其中start包括在结果end是没有的.留start空白意味着0,而留下end的空白意味着列表的末尾.

摘要

总而言之,您的完整代码(在介绍了一些更多的python习语之后enumerate)可能看起来像:

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)
Run Code Online (Sandbox Code Playgroud)

或者,如果每个元素需要一个像素,则可以用for循环体替换

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