0

I have a set of about 2000 files that look like: 10_20.txt, 10_21.txt, 10_21.txt, ... ,10_50.txt, ... , 11.20.txt, ... , 11.50.txt , ... , 20_50.txt

The first value in the file name, we'll call x, goes from 10-20 in steps of 1, and the second value in the file name, we'll call y, and goes from 20-50 in steps of 1.

Within these files, there is a load of values and another value I want to extract, which we'll call z.

I have written a program to cycle through the files and extract z from each file and add it to a list.

My question now is, if I have 2 numpy arrays that look like:

x = np.arange(10,20,1) y = np.arange(20,50,1)

and a z list that has ~2000 floats in it, what is the best way to plot how z depends on x and y? Is there standard way to do this?

I had been thinking it would be best to extract x, y and z from a file, and add them to a multidimensional array. If this is the case could anyone point me in the right direction of how to extract the x and y values out of the file name.

4
  • 1
    I don't understand what you have in mind; x, y and z are of different length, so what exactly do you want to plot? How do you define "depends"? Commented Dec 15, 2017 at 19:38
  • it appears that x and y connect to the filenames and these files have content you want to plot. can you show the contents ? is there more than one z value per file? Commented Dec 15, 2017 at 19:57
  • Each z value is contained within a file that has the x and y value in the title name . The only thing in the file that I want to plot is the z value, which I have extracted all into a big list. This has resulted in different sized arrays , but in reality each value of x and y have a specific z value they map to , so all array lengths should be the same. I am asking how best to approach this Commented Dec 15, 2017 at 19:58
  • @ShpielMeister , the files are big text files containing molecular orbital calculations , the only value that is relevant in there is an energy, which I have extracted for each file into a list. So more specifically, x and y specify a molecular geometry , and z gives the energy. I want to see how the energy varies as we go through x and y Commented Dec 15, 2017 at 20:02

2 Answers 2

2

Suppose you have a ready function, say read_z_from_file(filename), that returns the z-value contained in the file, you could go about it like this:

import numpy as np

x = np.arange(10,20,1, dtype = np.int)
y = np.arange(20,50,1, dtype = np.int)
z = np.zeros((x.shape[0],y.shape[0]))

for i,x0 in enum(x):
   for j,y0 in enum(y):
      filename = '{}_{}.txt'.format(x0,y0)
      z[i,j] = read_z_from_file(filename)

You can then visualise z with imshow or matshow from matplotlib. For instance:

from matplotlib import pyplot as plt
fix,ax = plt.subplots()
ax.imshow(z)
plt.show()

EDIT:

To respond to the questions of the OP, there is a multitude of ways to visualise your data. imshow and matshow do both about the same thing, but differ in the display details. Additionally, you can, among many others, produce contour plots or 3d surfaces. It depends a lot on what you want to see. Anyway, assuming that the code above does what you want, I show below some code that uses four different methods to display the same example data. You can find out more about these different methods with pythons in-built help() function and, of course, the matplotlib and numpy documentation pages.

import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D ##for the 3d surface plot
from matplotlib import cm

#non-integer spacing of the coordinates
x = np.linspace (10, 20, 15)
y = np.linspace (20, 50, 70)

#gridding the coordinates
xm, ym = np.meshgrid(x,y)

#example data
z = np.exp(-( 0.1*(xm-12)**2 + 0.05*(ym-40)**2 ) )

#opening a figure
fig = plt.figure(figsize=(6,6))

#matshow:
ax1 = fig.add_subplot(221)
res = ax1.matshow(
    z,
    origin = 'lower',
    aspect = 'auto',
    extent=[x[0],x[-1],y[0],y[-1]],
    )
fig.colorbar(res)
ax1.set_title('matshow', y=1.1)

#imshow
ax2 = fig.add_subplot(222)
res = ax2.imshow(
    z,
    origin = 'lower',
    aspect = 'auto',
    extent=[x[0],x[-1],y[0],y[-1]],
    )
fig.colorbar(res)
ax2.set_title('imshow')


#contourf
ax3 = fig.add_subplot(223)
res = ax3.contourf(xm,ym,z)
fig.colorbar(res)
ax3.set_title('contourf')

#3d surface
ax4 = fig.add_subplot(224, projection='3d')
res = ax4.plot_surface(
    xm,ym,z,
    cmap = cm.viridis,
    antialiased=False
)
fig.colorbar(res, pad = 0.1)
ax4.set_title('3d surface')

fig.tight_layout()
plt.show()

The final plot looks like this:

the result of the above given code

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, is there any easy way to modify this if I now have floats? E.g. if it's now x= 20.1, y = 50.2. As then the z[i,j] wouldnt work would it?
Yes, it would still work, because the 'i,j` are just the indices of the numpy array, but it would probably not be the best way to visualise your data anymore -- especially if your x and y are not equally spaced. There are, however, other possibilities like contour and contourf and 3d surface plots. If you tell me exactly what you have and want, I can give you a more precise answer.
Note that there was a small mistake in the code I gave -- it's corrected now.
Ok, if I have z as a 91x25 matrix, x as a 1x91 array and y as a 1x25 array, with z[i,j] giving the value of z at x[i], y[j], what would you suggest the best way to visualise this is ?
@loolipop please have a look at the edit in my answer.
0

use x and y as coordinates and put a dot sized for the energy z.

a table would work as well, since you haven't stated that x and y geometries have any numeric purpose other than as lablels.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.