Using Mayavi and Mlab to plot "bubbles" - python

Currently, I am attempting to plot some "bubble" like shapes in a 3D space using Mayavi/Mlab. These bubbles are represented by a numpy array of shape (840,1100,30) where the parameters represent (x,y,z) and the value at any x,y,z is either 1 or 0. The array can be thought of as a collection of Voxels that are either on or off. I try to plot this data with the following commands:
mlab.contour3d(finalVolume)
mlab.show()
But the plot is coming out in 2 dimensions instead of in 3 dimensions. I have looked at the documentation but am having trouble understanding. If anyone could provide some help or a push in the right direction, then I would be very appreciative!
Thanks!

Sounds like you need to use volume rendering to accomplish this. This can be accomplished using:
mlab.pipeline.volume(mlab.pipeline.scalar_field(s), vmin=0, vmax=0.8)
You will need to adjust the opacity transfer function using vmin and vmax to make an appropriate image. Examples on volume rendering can be found at: http://docs.enthought.com/mayavi/mayavi/mlab.html

Related

3D interpolation and plotting into a volume/isosurface on python

I'm looking for a way to interpolate 2D fields that are arranged on a list, making the shape data = [11,2016,2016]
Up to the moment I've managed to stack the 2D plots over the Z axis and create an interactive plot, but i want to create a plot of the volume and thought that an interpolation through the 11 steps would work, I'd like to get only one 2D array at the end to plot.
Any suggestions about how to perform this? can I make it on one single operation or am I obliged to perform step by step interpolations between each step?
edit: a picture showing the image that i'm able to generate now and can maybe explain better my problem.

Matplotlib: Using np.mgrid to create a cube surface plot

I do not understand how plot_surface and np.mgrid work together to create a face.
When I try I keep getting 3 faces in the shape of a 'Z'. I would like to see a proper example of a cube to understand this better.

slicing volume rendering graph in python

I have an input data with each row having (x,y,z,data), i.e., each coordinate (x,y,z) has a value "data". I would like to make a slicing volumetric graph like below in python. I am new to python, any tips would be much appreciated. see here for the example graph
If you have your data organized as a 2D array (n-points x 4) [x,y,z,data] (this can also be refered to as a point-cloud representations) and you want to display it as a volume rendering. You have to first resample it as a 3D array (interpolate 3D volume with numpy and or scipy) and then create an isosurface using marching cubes (How to display a 3D plot of a 3D array isosurface in matplotlib mplot3D or similar?)
You can also plot the values using a 3D scatter plot which is much easier, but won't get you the kind of plot you asked for (https://matplotlib.org/examples/mplot3d/scatter3d_demo.html)

Plotting 2D satellite profile data in 3D over earth projection in Python

I am attempting to do something similar to this:
sample ozone profile
Not necessarily over an orthographic projection - a cube over a map would suffice.
I'm able to plot the PolyCollection object produced by matplotlib.pyplot.pcolor, but cannot figure out if there's an accepted way of plotting the profile over an arbitrary lat/lon path.
The only thing I can think of right now is continuing to use pcolor() to get the face colors, then just modifying the vertices for each Poly object.
If you want to create a 3D projection, then you may use the plot_surface. It essentially draws a 2D array where the 3D coordinates of each vertex is given.
You might get some ideas by looking at this: Creating intersecting images in matplotlib with imshow or other function
The matplotlib solution there is essentially the same as using pcolor, but the 3D arithmetics is carried out by matplotlib. The suggestion to use mayavi is also something worth conisdering, as matplotlib is not at its strongest with 3D projected raster data.

Saving images in Python at a very high quality

How can I save Python plots at very high quality?
That is, when I keep zooming in on the object saved in a PDF file, why isn't there any blurring?
Also, what would be the best mode to save it in?
png, eps? Or some other? I can't do pdf, because there is a hidden number that happens that mess with Latexmk compilation.
If you are using Matplotlib and are trying to get good figures in a LaTeX document, save as an EPS. Specifically, try something like this after running the commands to plot the image:
plt.savefig('destination_path.eps', format='eps')
I have found that EPS files work best and the dpi parameter is what really makes them look good in a document.
To specify the orientation of the figure before saving, simply call the following before the plt.savefig call, but after creating the plot (assuming you have plotted using an axes with the name ax):
ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
Where elevation_angle is a number (in degrees) specifying the polar angle (down from vertical z axis) and the azimuthal_angle specifies the azimuthal angle (around the z axis).
I find that it is easiest to determine these values by first plotting the image and then rotating it and watching the current values of the angles appear towards the bottom of the window just below the actual plot. Keep in mind that the x, y, z, positions appear by default, but they are replaced with the two angles when you start to click+drag+rotate the image.
Just to add my results, also using Matplotlib.
.eps made all my text bold and removed transparency. .svg gave me high-resolution pictures that actually looked like my graph.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
# Do the plot code
fig.savefig('myimage.svg', format='svg', dpi=1200)
I used 1200 dpi because a lot of scientific journals require images in 1200 / 600 / 300 dpi, depending on what the image is of. Convert to desired dpi and format in GIMP or Inkscape.
Obviously the dpi doesn't matter since .svg are vector graphics and have "infinite resolution".
You can save to a figure that is 1920x1080 (or 1080p) using:
fig = plt.figure(figsize=(19.20,10.80))
You can also go much higher or lower. The above solutions work well for printing, but these days you want the created image to go into a PNG/JPG or appear in a wide screen format.
Okay, I found spencerlyon2's answer working. However, in case anybody would find himself/herself not knowing what to do with that one line, I had to do it this way:
beingsaved = plt.figure()
# Some scatter plots
plt.scatter(X_1_x, X_1_y)
plt.scatter(X_2_x, X_2_y)
beingsaved.savefig('destination_path.eps', format='eps', dpi=1000)
In case you are working with seaborn plots, instead of Matplotlib, you can save a .png image like this:
Let's suppose you have a matrix object (either Pandas or NumPy), and you want to take a heatmap:
import seaborn as sb
image = sb.heatmap(matrix) # This gets you the heatmap
image.figure.savefig("C:/Your/Path/ ... /your_image.png") # This saves it
This code is compatible with the latest version of Seaborn. Other code around Stack Overflow worked only for previous versions.
Another way I like is this. I set the size of the next image as follows:
plt.subplots(figsize=(15,15))
And then later I plot the output in the console, from which I can copy-paste it where I want. (Since Seaborn is built on top of Matplotlib, there will not be any problem.)

Categories

Resources