简体   繁体   English

Matplotlib pcolor

[英]Matplotlib pcolor

I am using Matplotlib to create an image based on some data. 我正在使用Matplotlib根据一些数据创建图像。 All of the data falls in the range of 0 through to 1 and I am trying to color the data based on its value using a colormap and this works perfectly in Matlab, however when converting the code across to Python I simply get a black square as the output. 所有数据都在0到1的范围内,我试图使用色彩图基于其值对数据进行着色,这在Matlab中完美运行,但是当将代码转换为Python时,我只需得到一个黑色正方形输出。 I believe this is because I'm plotting the image wrong and so it is plotting all the data as 0. I have tried searching this problem for several hours and I have tried plt.set_clim([0, 1]) however that didn't seem to do anything. 我相信这是因为我正在绘制错误的图像,所以它将所有数据绘制为0.我已经尝试了几个小时搜索这个问题而且我已经尝试了plt.set_clim([0, 1])但是那并没有好像什么都做。 I am new to Python and Matplotlib, although I am not new to programming (Java, javascript, PHP, etc), but I cannot see where I am going wrong. 我是Python和Matplotlib的新手,虽然我不是编程新手(Java,javascript,PHP等),但我看不出我哪里出错了。 If any body can see anything glaringly incorrect in my code then I would be extremely grateful. 如果任何身体在我的代码中可以看到任何明显不正确的内容,那么我将非常感激。

Thank you 谢谢

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')

Although you have resolved your original issue and have code that works, I wanted to point out that both python and numpy provide several tools that make code like this much simpler to write. 虽然你已经解决了原始问题并且代码有效,但我想指出python和numpy都提供了一些工具,使得这样的代码编写起来更加简单。 Here are a few examples: 这里有一些例子:

Loading data 加载数据中

Instead of building up lists by appending to the end of an empty one, it is often easier to generate them from other lists. 不是通过附加到空列表的末尾来构建列表,而是通过其他列表生成列表通常更容易。 For example, instead of 例如,而不是

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

you can simply write: 你可以简单地写:

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

The syntax [x(y) for y in l] is known as a list comprehension , and, in addition to being more concise will execute more quickly than a for loop. 语法[x(y) for y in l]被称为列表推导 ,并且除了更简洁之外,它将比for循环更快地执行。

However, for loading tabular data from a text file, it is even simpler to use numpy.loadtxt : 但是,要从文本文件加载表格数据,使用numpy.loadtxt更简单:

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

for more information, 欲获得更多信息,

print np.loadtxt.__doc__

See also, its slightly more sophisticated cousin numpy.genfromtxt 另见,其稍微复杂的堂兄numpy.genfromtxt

Reshaping data 重塑数据

Now that we have our data loaded, we need to reshape it. 现在我们已经加载了数据,我们需要重塑它。 The while loops you use work fine, but numpy provides an easier way. 你使用的while循环工作正常,但numpy提供了一种更简单的方法。 First, if you prefer to use your method of loading the data, then convert your eigenvector arrays into proper numpy arrays using e1cx = array(e1cx) , etc. 首先,如果您更喜欢使用加载数据的方法,那么使用e1cx = array(e1cx)等将您的特征向量数组转换为适当的numpy数组。

The array class provides methods for rearranging how the data in an array is indexed without requiring it to be copied. array类提供了重新排列数组中数据索引的方法,而无需复制它。 The simplest method is array.reshape , which will do half of what your while loops do: 最简单的方法是array.reshape ,它将执行while循环的一半:

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

Here, almost_fx is a rank-3 array indexed as almost_fx[iz,iy,ix] . 这里, almost_fx是一个rank-3数组,索引为almost_fx[iz,iy,ix] One important thing to be aware of is that e1cx and almost_fx share their data. 需要注意的一件重要事情是e1cxalmost_fx共享他们的数据。 So, if you change e1cx[0,0] , you will also change almost_fx[0,0,0] . 因此,如果更改e1cx[0,0] ,您还将更改almost_fx[0,0,0]

In your code, you swapped the x and y locations. 在您的代码中,您交换了x和y位置。 If this is indeed what you wanted to do, you can accomplish this with array.swapaxes : 如果这确实是你想要做的,你可以使用array.swapaxes完成这个:

fx = almost_fx.swapaxes(1,2)

Of course, you could always combine this into one line 当然,您总是可以将它组合成一行

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

However, if you want the z-slices ( fx[z,:,:] ) to plot with x horizontal and y vertical, you probably do not want to swap the axes above. 但是,如果您希望z切片( fx[z,:,:]以x水平和y垂直绘图,您可能不希望交换上面的轴。 Just reshape and plot. 只是重塑和策划。

Slicing arrays 切片阵列

Finally, rather than looping over the z-index and testing for multiples of 10, you can loop directly over a slice of the array using: 最后,不是循环遍历z-index并测试10的倍数,而是可以使用以下方法直接在数组的一个切片上循环:

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

This indexing syntax is array[start:end:step] where start is included in the result end is not. 这个索引语法是array[start:end:step]其中, start被包括在结果end是没有的。 Leaving start blank implies 0, while leaving end blank implies the end of the list. start空白表示为0,而将end空白表示列表的结尾。

Summary 摘要

In summary your complete code (after introducing a few more python idioms like enumerate ) could look something like: 总之,您的完整代码(在介绍了一些像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)

Alternatively, if you want one pixel per element, you can replace the body of the for loop with 或者,如果每个元素需要一个像素,则可以用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