Integrals - 1 year ago 95
Python Question

# Making a quiver plot from .dat files

Hi I am trying to make a quiver (vector field) plot from data that is stored in .dat files. I have 4 .dat files which are 1D arrays, one for the x axis, y axis, f(x,y) along x and f(x,y) along y.

Note, I am able to construct a quiver plot without importing data from .dat files, I just followed this basic example here.

However, I am unable to apply this basic example to my example in which I need to import the data from .dat files. My code is below, I am not getting any error messages but I am getting a blank quiver plot. Any help/suggestions would be greatly appreciated, thanks!

``````import numpy as np
import matplotlib.pyplot as plt

n=12

data0 = np.genfromtxt('xaxis.dat')
data1 = np.genfromtxt('yaxis.dat')
data2 = np.genfromtxt('fx.dat')
data3 = np.genfromtxt('fy.dat')

x  = data0[0]
y  = data1[0]
fx = data2[0]
fy = data3[0]

plt.axes([0.025, 0.025, 0.95, 0.95])
plt.quiver(x,y,fx,fy, alpha=.5)
plt.quiver(x,y,fx,fy,edgecolor='k',facecolor='none', linewidth=.5)

plt.xlim(-1,n)
plt.xticks(())
plt.ylim(-1,n)
plt.yticks(())

plt.show()
``````

In the example for the quiver plot you provided all `X`, `Y`, `U` and `V` are 2D arrays, with shape `(n,n)`.

In your example you are importing an array of values for `x`, `y`, `fx` and `fy`, and then selecting only the first line with `[0]`.

When using the code:

``````import numpy as np
import matplotlib.pyplot as plt

n=3 # number of points, changed it

data0 = np.genfromtxt('xaxis.dat')
data1 = np.genfromtxt('yaxis.dat')
data2 = np.genfromtxt('fx.dat')
data3 = np.genfromtxt('fy.dat')

x  = data0[0]
y  = data1[0]
fx = data2[0]
fy = data3[0]

plt.axes([0.025, 0.025, 0.95, 0.95]) # position of bottom left point of graph inside window and its size
plt.quiver(x,y,fx,fy, alpha=.5) # draw inside of arrows, half transparent
plt.quiver(x,y,fx,fy,edgecolor='k',facecolor='none', linewidth=.5) # draw contours of arrows

plt.xlim(-1,n) # left and right most values in the x axis
plt.xticks(()) # remove the numbers from the x axis
plt.ylim(-1,n) # ...
plt.yticks(()) # ...

plt.show()
``````

I get: With `0 1 2 0 1 2 0 1 2` in xaxis.dat and fx.dat, `0 0 0 1 1 1 2 2 2` in yaxis.dat and `1 1 1 2 2 2 3 3 3` in fy.dat. If I just remove the `[0]` from the arrays assignment, I get: with all points shown.

One change I would make is to use `plt.xlim(min(x)-1,max(x)+1)` and `plt.ylim(min(y)-1,max(y)+1)`, to ensure you get to view the right area of the graph. For instance, if I make all four arrays equal to `np.random.rand(10)` (a 1D array with 10 random elements between 0 and 1), I get:

## Notes on array shape

The `plt.quiver` will also accept the arrays in the format:

``````x  = [0, 1, 2] # 1D array (list, actually...)
y  = [0, 1, 2]
fx = [[0, 1, 2],
[0, 1, 2],
[0, 1, 2]] # 2D array
fy = [[0, 0, 0],
[1, 1, 1],
[2, 2, 2]]
``````

But will not mesh automatically if all arrays are 1D (in which case it will repeat `x` and `y` without the correct structure:

``````fx = np.array(fx).flatten()
fy = np.array(fy).flatten()
``````

So either have:

``````x = [0, 1, 2, 3]
y = [4, 5, 6]
fx = [[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3]]
fy = [[4, 4, 4, 4],
[5, 5, 5, 5],
[6, 6, 6, 6]]
``````

and let `plt` do the mesh for you, or have all arrays with the same shape and `plt.quiver` will get each arrow's position and components from them per index:

``````x = [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]
y = [4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6]
fx = [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]
fy = [4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6]
``````

[first two paragraphs]...

This means you probably noticed `genfromtxt` returns a 2D array (as it is able to import several columns from a single file, so the returned array will mimic the 2D structure of your file if nothing else is told), making `data0[0]` the first line on your document xaxis.dat.

EDIT: the sentence below is erroneous, plt.quiver can receive 1D arrays, just in the right shape.

However the `quiver` expects 2D arrays, from where it will retrieve the values for each point: for point `i,j` the position will be `(X[i,j], Y[i,j])` and the arrow will be `(U[i,j], V[i,j])`.

If you have the repeated values for x and y in the file like this:

• xaxis.dat:

0, 1, 2, 0, 1, 2, 0, 1, 2

• yaxix.dat:

0, 0, 0, 1, 1, 1, 2, 2, 2

You can just reshape all four of your arrays to (# points in x, # points in y) and it should work out.

If you don't you will have to use something similar to `np.mgrid` (or `np.meshgrid`) to make a valid combination of `X` and `Y` arrays, and format `fx` and `fy` accordingly.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download