masking an imshow, or imshow with RGBA - python

A dataframe, which should be considered a matrix, contains values 0, 1, 2.
With imshow, I get a nice image. I can use a cmap with 3 discrete colors.
I want to highlight few rows, so visually I want to have those rows with alpha=1 and the other with alpha=0.1 .
Should I create the image myself, creating a matrix with RGBA entries?
Is there a more straight-forward way?
With Kind Regards,
Oren

I found a nice way to do that with Layer Images.
https://matplotlib.org/gallery/images_contours_and_fields/layer_images.html#sphx-glr-gallery-images-contours-and-fields-layer-images-py
Apparently I can imshow the matrix with the intended highlighted colors. And on top of that, add a imshow with values that are either the same, where I want to highlight, or white otherwise. I then make sure to have alpha=0.5 for example, for the second imshow.

Related

basemap set_bad() for Nan values

I have tried to use numpy masked array and basemap module to plot raster data with no-data values. I defined a color map as cmap and then used cmap.set_bad(color='grey') to set no-data value to color gray. I then use contourf(...,cmap=cmap) to plot the raster, however, the no-data is still shown as white color.
I have been searching a lot of examples of "set_bad", it looks like it works fine for imshow() function. I wonder does anyone have any experience using contourf and set_bad to show the raster images with nodata values?
Thanks a lot for your help.

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.

Proper way to overlay multiband images?

I want to overlay two views of the same scene - one is a white-light image (monochrome, used for reference) and the other is an image in a specific band (that has the real data I'm showing).
The white-light image is "reference", the data image is "data". They're ordinary 2D numpy arrays of identical dimensions. I want to show the white reference image using the 'gray' color map, and the data image using the 'hot' color map.
What is the "proper" way to do this?
I started with this:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
hotm = cm.ScalarMappable(cmap='hot')
graym = cm.ScalarMappable(cmap='gray')
ref_rgb = graym.to_rgba(reference) # rgba reference image, 'gray' color map
data_rgb = hotm.to_rgb(data) # rgba data image, 'hot' color map
plt.imshow(ref_rgb + data_rgb)
That didn't work well because in the plt.imshow() call the sum overflowed the range 0..1 (or maybe 0..255; this is confusing) and gave me crazy colors.
Then I replaced the last line with this:
plt.imshow(ref_rgb/2 + data_rgb/2)
That worked, but gives me a very washed-out, low-contrast image.
Finally, I tried this:
plt.imshow(np.maximum(ref_rgb, data_rgb))
That seems to give the best result, but I'm worried that much of my "data" is lost by having lower r, g, or b values than the reference image.
What is the "proper", or "usual" way to do this?
I'm not exactly sure what you're trying to achieve, but hopefully this will give you some ideas. :)
I've never used matplotlib, but from a quick look at the docs, it looks like matplotlib.cm gives you the option to have the pixel data as integers in the 0..255 range or as floats in the 0.0..1.0 range. The float format is more convenient for arithmetic image processing, so I'll assume that's the case in the rest of this answer.
We can do basic image processing by doing simple arithmetic on the RGB pixel values. Roughly speaking, adding (or subtracting) a constant to the RGB value of all your pixels changes the image brightness, multiplying your pixels by a constant changes the image contrast, and raising your pixels to a constant (positive) power changes the image gamma. Of course, you do need to make sure that these operations don't cause the colour values to go out of range. That's not a problem for gamma adjustment, or contrast adjustment (assuming the constant is in the 0.0..1.0 range), but it can be a problem for brightness modification. More subtle brightness & contrast modification can be achieved by suitable combinations of addition and multiplication.
When doing this sort of thing it's often a Good Idea to normalize the pixel values in your image data to the 0.0..1.0 range, either before &/or after you've done your main processing.
Your code above is essentially treating the grey reference data as a kind of mask and using its values, instead of using a constant, to operate on the colour data pixel by pixel. As you've seen, taking the mean of ref_rgb & data_rgb results in a washed-out image because you are reducing the contrast. But see what happens when you multiply ref_rgb & data_rgb: contrast will generally be increased because dark areas in ref_rgb will darken the corresponding pixels in data_rgb but bright areas in ref_rgb will leave the corresponding pixels in data_rgb virtually untouched.
ImageMagick has some nice examples of arithmetic image processing.
Another thing to try is to convert your data_rgb to HSV format, and replace the V (value) data with the greyscale data from ref_rgb. And you can do similar tricks with the S (saturation) data, although the effect is generally a bit subtler.

When to use imshow over pcolormesh?

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.

highlight regions of no data in a Python imshow plot

I am producing an imshow plot in Python.
In the final plot, I have strips/columns of data, between which there is no data at all - kind of like a barcode.
At the moment, where I have no data, I have just set all values to zero. The color of these regions of no data is therefore whatever colour represents zero in my colorbar - green in my case.
What I really want is for these columns/strips just to be white, and to make to really clear that these are regions of NO data.
I realise that I could change the colorbar so that the zero is white, but I really want to distinguish the regions of no data from any zeros that might be in the data.
Thank you.
try setting those values to np.nan ( or float('nan')); you may also want to pass interpolation='nearest' to imshow as an argument.

Categories

Resources