When to use imshow over pcolormesh? - python

I often find myself needing to create heatmap-style visualizations in Python with matplotlib. Matplotlib provides several functions which apparently do the same thing. pcolormesh is recommended instead of pcolor but what is the difference (from a practical point of view as a data plotter) between imshow and pcolormesh? What are the pros/cons of using one over the other? In what scenarios would one or the other be a clear winner?

Fundamentally, imshow assumes that all data elements in your array are to be rendered at the same size, whereas pcolormesh/pcolor associates elements of the data array with rectangular elements whose size may vary over the rectangular grid.
If your mesh elements are uniform, then imshow with interpolation set to "nearest" will look very similar to the default pcolormesh display (without the optional X and Y args). The obvious differences are that the imshow y-axis will be inverted (w.r.t. pcolormesh) and the aspect ratio is maintained, although those characteristics can be altered to look like the pcolormesh output as well.
From a practical point of view, pcolormesh is more convenient if you want to visualize the data array as cells, particularly when the rectangular mesh is non-uniform or when you want to plot the boundaries/edges of the cells. Otherwise, imshow is more convenient if you have a fixed cell size, want to maintain aspect ratio, want control over pixel interpolation, or want to specify RGB values directly.

Related

How to make a contour plot with three variables in a dataset?

I am trying to generate a contour graph in terms of three parameters (say x, y, z). These parameters come from a data table of more than 5000 values.I need the graphics to look like the figures shown below.
Contour plots are most easily made using matplotlib's contour.
There's also a corresponding contourf function that provides filled contours. Anyway, what you uploaded looks more like matplotlib's pcolor or pcolormesh, as they draw colored pixels instead of isovalue lines.
Here's a nice comparison of both if you need to choose.
Edit: For (x,y,z) points that are not distributed on a grid (i.e. come from random samples), a working solution seems to be a combination of binned_statistic_2d and then either plt.pcolor or plt.contour.

Set colorbar range for an mlab surface

I've looked around on the internet but I haven't found a solution.
I'm plotting different surfaces in the same figure with mlab.pipeline.surface(mesh). I'd like to plot them with the same colorbar.
In this figure the right part of the surfaces is at the same temerature, but since the colorbar range is different for each surface the color is different.
I think there should be something like matplotlib.tricontourf(...,levels=...) to fix the colorbar range.
How can I set the colorbar range using mlab?
You can take a look at the built-in documentation of mlab. From help(mlab.pipeline.surface):
:vmax: vmax is used to scale the colormap.
If None, the max of the data will be used
:vmin: vmin is used to scale the colormap.
If None, the min of the data will be used
In other words, you need to compute the global minimum and global maximum of your data across every dataset, and set the same extrema for every surface of yours. Note that you can do the exact same (with the exact same keywords even) with matplotlib's 3d plotting methods.
Tangential note: your use case might also benefit from some transparency, since your surfaces are likely to overlap one another which might hinder the visualization. The two keywords that come to mind are opacity and perhaps (albeit less likely) transparent:
:opacity: The overall opacity of the vtk object. Must be a float.
Default: 1.0
:transparent: make the opacity of the actor depend on the
scalar.

matplotlib surface plot limited by the boundaries

Is there any kind of chance to "cut" the surface plot (x,y,z) made by use of the matplotlib by some well defined boundaries, so that I can draw any kind of shape in 3D. Now I can do that but x,y are 2D arrays (meshgrid) and the shape is always rectangular.
Example:
Here, the plate has a base-shape of rectangular (2d-array are used). The z coordinates are derived by some function f=f(x,y).
What I would like achieve is shown in the picture below (made by hand ;)). One idea is to turn-off a single cell. But how to make the cells transparent?
What you'd like is to mask some regions in the surface. Unfortunately, matplotlib does not support masked arrays yet for plot_surface, but you could circumvent it by using np.nan for those masked regions.
It is also detailed in plotting-a-masked-surface-plot-using-python-numpy-and-matplotlib.

rasterizing matplotlib axis contents (but not frame, labels)

For an article I am generating plots of deformed finite element meshes, which I visualize using matplotlib's polycollection. The images are saved as pdf.
Problems arise for high density meshes, for which the naive approach results in files that are too large and rendering too intensive to be practical.
For these meshes it really makes no sense to plot each element as a polygon; it could easily be rasterized, as is done when saving the image as jpg or png. However, for print I would like to hold on to a sharp frame, labels, and annotations.
Does anyone know if it is possible to achieve this kind of hybrid rasterization in matplotlib?
I can think of solutions involving imshow, and bypassing polycollection, but I would much prefer to use matplotlib's built-in components.
Thanks for your advice.
Just pass the rasterized=True keyword to your collection constructor. Example:
col = collections.PolyCollection(<arguments>, rasterized=True)
This allows a selective rasterization of that element only (e.g., if you did a normal plot on top of it, it would be vectorized by default). Most commands like plot or imshow can also take the rasterized keyword. If one wants to rasterize the whole figure (including labels and annotations), this would do it:
fig = plt.figure()
a = fig.add_subplot(1,1,1, rasterized=True)
(But this is not what you want, as stated in the question.)

How to force color mapping to a dynamic range larger than the particular input to imshow in matplotlib

Suppose I want to make 2+ heatmaps (on the same, or different Figures) and have the color<->value mapping be the same among them.
By default, the extreme values in the colormap (say jet) will be used for the dynamic range of each heatmap individually (i.e. each call to imshow), and I'd like to force the mapping to be the same, i.e. use the global dynamic range.
I think an equivalent statement is that I'd like to somehow specify an absolute mapping, whereas the behavior of imshow given a cmap object, is relative to the dynamic range of the input.
If you don't want to specify the ranges but somehow you know that one plot has the largest range, you can get that range with Axesimage.properties()['clim'] and set it for the other plots as I explained here: Imshow subplots with the same colorbar

Categories

Resources