How can I overlay mutliple heatmaps using matplotlib? - python

I am simulating range-doppler maps for target detection in a radar.
What I'm currently trying to accomplish is have multiple targets on one range doppler map.
I tried messing with imshow's alpha argument, but it seems to blur/dim the entire image. Also, as I add more targets, the dots become harder to see, as shown below.
Is there a way to modify the premade matplotlib colormaps (such as hot or cool) so that brighter points are kept while the darker background is faded, allowing you to see all bright points clearly?
Target 1, Target 2, Both targets overlayed, Adding a third target
Here is where I am plotting the images (when I add the third target, I use an alpha of 0.2):
plt.imshow(dopplerMaps[0], cmap='hot', interpolation='nearest', extent=[rangeAxis[0], rangeAxis[len(yt[0])-1], dopplerAxis[len(YT)-1], dopplerAxis[0]], alpha=1.0)
plt.imshow(dopplerMaps[1], cmap='hot', interpolation='nearest', extent=[rangeAxis[0], rangeAxis[len(yt[0])-1], dopplerAxis[len(YT)-1], dopplerAxis[0]], alpha=0.5)
plt.show()
Is there a better way to do this?
Thank you so much for anything!
Edit: the array dopperMaps contains several magnitudes of fourier transforms calculated earlier, if that helps to understand the photos. Also, the axis arrays are just for setting the bound of the plot.

Related

How to change the scale of an image to overlay with points in Matplotlib? [duplicate]

I want to create a figure that shows a background image with overlaid scatter and line plots:
As you can see, the axes ticks show image coordinates. The scatter and line plot are given in image coordinates, too - which is not desired. The scatter and line plots should still be able to work (and be meaningful) without the background image. The extent is not known because this figure is used to determine the extent (interactively) in the first place.
Instead, I'd like to specify the scatter and line plots in the coordinate system shown in the background image (units m³/h and m): the transformation from image coordinates to "axis on top" coordinates would be roughly (110,475) -> (0,10) and (530,190) -> (8,40).
In principle I can see two ways of doing it:
specify image extent after it has been added. However, I don't see this documented anywhere; This example shows how it's done when the extent is known at the call to imshow(): Plot over an image background in python
add an axes on top of the image axes with twinx and twin y, where both x,x and y,y pairs are tightly coupled. I have only seen features that allow me to specify a shared x or a shared y axis, not both.
The restriction here seems to be that "The scatter and line plots should still be able to work (and be meaningful) without the background image.". This however would not imply that you cannot use the extent keyword argument.
At the time you add the image, you'd specify the extent.
plt.scatter(...)
plt.plot(...)
plt.imshow(..., extent = [...])
You can also set the extent later, if that is desired for some reason not explained in the question, i.e.
plt.scatter(...)
plt.plot(...)
im = plt.imshow(...)
im.set_extent([...])
Finally you may also decide to remove the image, and plot it again; this time with the desired extent,
plt.scatter(...)
plt.plot(...)
im = plt.imshow(...)
im.remove()
im = plt.imshow(..., extent=[...])

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.

Making the marker size as small as possible with matplotlib.pyplot

My program can generate up to 2000000 points within 5 seconds, so I don't have a problem with speed. Right now I am using matplotlib.pyplot.scatter to scatter all my points on my graph. For s=1, it gives me small circles, but not small enough, because it does not show the intricate patterns. When I use s=0.1, it gives me this weird marker shape:
Which makes the marker larger despite me making the size smaller. I have searched all over the internet including stack overflow, but they do not tell how to minimize the size further. Unfortunately, I have to show all the points, and cannot just show a random sample of them.
I have come to the conclusion that matplotlib is made for a small sample of points and not meant for plotting millions of points. However, if it is possible to make the size smaller please let me know.
Anyway, for my points, I have all the x values in order in one array, and all the y values in order in another array. Could someone suggest a graphing package in python I could use to graph all the points in a way that the size would be very small since when I plot the points now it just becomes one big block of color instead of intricate designs forming in the shape as they should be.
Thanks for any help in advance!
EDIT: My code that I am using to scatter the points is:
plt.savefig(rootDir+"b"+str(Nvertices)+"_"+str(xscale)+"_"+str(yscale)+"_"+str(phi)+"_"+str(psi)+"_"+CurrentRun+"_color.png", dpi =600)
EDIT: I got my answer, I added linewidths = 0 and that significantly reduced the size of the points, giving me what I needed.
Perhaps you can try making the linewidths as 0 i.e., the line width of the marker edges. Notice the difference in the two plots below
fig, ax = plt.subplots(figsize=(6, 4))
plt.scatter(np.random.rand(100000), np.random.rand(100000), s=0.1)
fig, ax = plt.subplots(figsize=(6, 4))
plt.scatter(np.random.rand(100000), np.random.rand(100000), s=0.1, linewidths=0)
you can set the marker to a single pixel using marker=',' in your call to scatter.
See the markers documentation here

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.

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.)

Categories

Resources