Plotting 3D points with Python Matploltlib - python

I want to create a small simulation, and I think I know how, but in order to actually see what happens I need to visualize it.
I started with a 5x5x5 array, which I want to fill up with values.
data = numpy.zeros(shape=(5,5,5))
data[:,:,0]=4
data[:,:,1]=3
data[:,:,2]=2
data[:,:,3]=1
data[:,:,4]=0
This should create a cube which has a gradient in the upward direction (if the third axis is z).
Now, how can I plot this? I dont want a surface plot, or wireframe. Just Points on each coordinate, and maybe colorcoded or transperency by value.
As a test I tried plotting all coordinates using
ax.scatter(numpy.arange(5),numpy.arange(5),numpy.arange(5))
but this will only plot a line consisting of 5 dots.
So... how can I get the 125 dots, that I want to create?
Thx.

You can encode the value in color like this:
x = np.arange(5)
X, Y, Z = np.meshgrid(x,x,x)
v = np.arange(125)
ax.scatter(X,Y,Z, c=v)
See here for the documention.

Related

Visualization using pcolormesh in python

in my script I use plt.pcolormesh to visualize my data.
The following code is a simplification, but should help me to explain my problem.
In the example I created two vectors X and Y, both containing values from 0 to 9.
X and Y represent coordinates.
Z is defined to have the value 2, only the points between the X/Y-coordinates 3 and (including) 6 get the value 4.
Hence, Z can be seen as value for each coordinate.
My aim is to use plt.pcolormesh to color the area between these coordinates in a different color than the surrounding area.
But if I use plt.pcolormesh, also the quadrant above and to the right of the X/Y-coordinate is colored.
I know that I simply could change the definition of my X/Y-variables, but this isn't possible in my original code.
Thus, I want you to ask if there is a function in python which works similar to plt.pcolormesh, but only colors the area between my defined coordinates?
I hope, someone can help me ;)
X, Y = np.mgrid[slice(0,10,1), slice(0,10,1)]
Z = 2 * np.ones((10,10))
Z[3:7,3:7] = 4
plt.figure()
plt.pcolormesh(X, Y, Z, cmap=cm.rainbow)
plt.title('Test Meshgrid')
plt.colorbar()
Best regards,
Kai

Interpolate a curve on itself using NumPy

I have the following curve as two arrays, of x and y positions.
Imagine if you were to draw vertical lines going through each point, and add points on the curve wherever these lines intersect the curve. This is what I want.
I tried using np.interp(x, x, y), but I ended up with the following mess:
How can I do this? Is it possible with np.interp?
This might be something that should be asked in a different question, but I would also like there to be points added where the curve crosses over itself.
According to the docs the array of X values should be sorted (or periodic), otherwise "the result is nonsense". You can try to split your curve into sections, and then interpolate each part on the others. You can find the correct splitting places by looking at where np.diff(x) changes sign.

Plotting a 3D Cylindrical Surface plot in Python

I am trying to create a cylindrical 3D surface plot using Python, where my independent variables are z and theta, and the dependent variable is radius (i.e., radius is a function of vertical position and azimuth angle).
So far, I have only been able to find ways to create a 3D surface plot that:
has z as a function of r and theta
has r as a function of z, but does not change with theta (so, the end product looks like a revolved contour; for example, the case of r = sin(z) + 1 ).
I would like to have r as a function of z and theta, because my function will produce a shape that, at any given height, will be a complex function of theta.
On top of that, I need the surface plot be able to have (but does not have to have, depending on the properties of the function) an open top or bottom. For example, if r is constant from z = 0 to z = 1 (a perfect cylinder), I would want a surface plot that would only consist of the side of the cylinder, not the top or bottom. The plot should look like a hollow shell.
I already have the function r defined.
Thanks for any help!
Apparently, after some trial and error, the best/easiest thing to do in this case is to just to convert the r, theta, and z data points (defined as 2D arrays, just like for an x,y,z plot) into cartesian coordinates:
# convert to rectangular
x = r*numpy.cos(theta)
y = r*numpy.sin(theta)
z = z
The new x,y,z arrays can be plotted just like any other x,y,z arrays generated from a polynomial where z is a function of x,y. I had originally thought that the data points would get screwed up because of overlapping z values or maybe the adjacent data points would not be connected correctly, but apparently that is not the case.

Getting correct XY axes when plotting numpy array

Beginning python/numpy user here. I do an analysis of a 2D function in the XY plane. Using 2 loops through x and y I compute the function value and store it into an array for later plotting. I ran into a couple of problems.
Lets say my XY range is -10 to 10. How do I accommodate that when storing computed value into my data array? (only positive numbers are allowed as indices) For now I just add to x and Y to make it positive.
From my data I know that the extreme is a x=-3 and y=2. When I plot the computed array first of all the axes labels are wrong. I would like Y to go the mathematical way. (up)
I would like the axes labels to run from -10 to 10. I tried 'extend' but that did not come out right.
Again from my data I know that the extreme is at x=-3 and y=2. In the plot when I hover the mouse over the graphics, the max value is shown at x=12 and y=7. Seems x and y have been swapped. Though when I move the mouse the displayed x and y numbers run as follows. X grows larger when moving the mouse right etc. (OK) Y runs the wrong way, grows larger when moving DOWN.
As side note it would be nice to have the function value shown in the plot window as well next to x and y.
Here is my code:
size = 10
q = np.zeros((2*size,2*size))
for xs in range(-size,+size):
for ys in range(-size,+size):
q[xs+size,ys+size] = my_function_of_x_and_y(x,y)
im = plt.imshow(q, cmap='rainbow', interpolation='none')
plt.show()
One more thing. I would like not to mess with the q array too badly as I later want to find the extreme spot in it.
idxmin = np.argmin(q)
xmin,ymin = np.unravel_index(idxmin, q.shape)
xmin= xmin-size
ymin= ymin-size
So that I get this:
>>> xmin,ymin
(-3, 2)
>>>
Here is my plot:
(source: dyndns.ws)
Here is the desired plot (made in photoshop) (axis lineswould be nice):
(source: dyndns.ws)
Not too sure why setting extend did not work for you but this is how I have implemented it
q = np.random.randint(-10,10, size=(20, 20))
im = plt.imshow(q, cmap='rainbow', interpolation='none',extent=[-10,10,-10,10])
plt.vlines(0,10,-10)
plt.hlines(0,10,-10)
plt.show()
Use vlines and hlines methods to set the centering line

Matplotlib 3D hypocenter plot, reading xyz values from .txt file

I am trying to learn python by doing. I have real world xy (lat long dd) coordinates and z (km below surface) values for about 500,000 earthquakes (hypocenter) from M 0.1 to 2.0. I chopped the data down to 10 rows of xyz values in a .txt tab delimited table. I want to plot the data in a 3d scatter plot rotatable box in matplotlib. I can use basic commands to read the data and the format looks fine. I am not clear if I need to read the data into a list or array for mpl to read and plot the data. Do I need to create an array at all?
I then want to plot the subsurface location of an oil well, given the xyz coordinates of vertices along the well bore (about 40 positions), do I need to create a polyline?. This data has the same general coordiantes (to be evaluated further) as some of the hypcenters. Which set of data should be the plot, and which should be the subplot? Also, I am unclear as to the "float" that I need given the 6 to 7 decimal places of he xy lat long coordinates, and the 2 decimal z coordinates.
Matplotlib is a poor choice for this, actually. It doesn't allow true 3D plotting, and it won't handle the complexity (or number of points in 3D) that you need. Have a look at mayavi instead.
Incidentally, it sounds like you're doing microseismic? (I'm a geophysist, as well, for whatever it's worth.)
As a quick example:
from enthought.mayavi import mlab
import numpy as np
# Generate some random hypocenters
x, y, z, mag = np.random.random((4, 500))
# Make a curved well bore...
wellx, welly, wellz = 3 * [np.linspace(0, 1.5, 10)]
wellz = wellz**2
# Plot the hypocenters, colored and scaled by magnitude
mlab.points3d(x, y, z, mag)
# Plot the wellbore
mlab.plot3d(wellx, welly, wellz, tube_radius=0.1)
mlab.show()
As far as reading in your data goes, it sounds like it should be as simple as:
x, y, z = np.loadtxt('data.txt').T
What problems have you run in to?

Categories