I need to create a streamplot with a colorbar indicating the speed of a given line. The thing is, there's 2 points in my speed data with excessive value, totally rescaling the scale of the colorbar, and I can't really erase them.
I've searched way to prevent it without modifying the data (like with cmin, Vmin, Vmax...), but it seems streamplot doesn't have function for this...
So is there a way to add limits to the cmap in a streamplot ?
Related
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.
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.
I have a set of PDF that I need to plot for a certain section of the PDF domain. However, when I plot my lines on a 3d plot I get tails for each PDF,
Is there a clean way to not plot the tails that happen outside my plot limits? I know I can change the data to NaNs to achieve the same effect but I want to do this in matplotlib. Here is my current workaround code,
`# trim the data
y = np.ones(PDF_x.shape)*PDF_x
y[y>95]= np.nan
y[y<75]= np.nan
# plot the data
fig = plt.figure()
ax = fig.gca(projection='3d')
for i in range(PDF_capacity.shape[1]):
ax.plot(life[i]*np.ones((PDF_x.shape)),y,PDF_capacity[:,i], label='parametric curve')
# set the axis limits
ax.set_ylim(75,95)
# add axis labels
ax.set_xlabel('charge cycles to failure point of 75% capacity')
ax.set_ylabel('capacity at 100 charge cycles')
ax.set_zlabel('probability')`
After trimming I can make the following plot,
Masking the data with nan in the way you're doing it is a good and practical solution.
Since matplotlib 3D plots are projections into 2D space, it would be hard to implement automatic clipping. While I do think it would be possible, I'm not convinced that it's worth the effort. First, because you would need to treat different kinds of plots differently, second, because at least in some cases it would probably turn out that masking the data is still the best choice. Now, doing a complex subclassing of the plotting objects just to do the same thing that can be manually done in one or two lines is probably overkill.
My clear recommendation would therefore be to use the solution you already have. Especially since it does not seem to have any drawbacks so far.
Is it possible to force plt.scatter into the same color levels as plt.contourf and plt.contour? For example, I have code that makes a plot like this:
to make the first subplot, I use
cs=m[0].scatter(xs,ys,c=obsData,cmap=plt.cm.jet)
m.colorbar(cs)
To make the second subplot, I use
cs2=m[1].contourf(x,y,areaData,cmap=cs.cmap)
And for each subsequent subplot, I use
m[ind].contourf(x,y,areaData,cmap=cs.cmap,levels=cs2.levels
where areaData is recalculated within a loop.
My question is, how can I force the first subplot to have the same colors as the other subplots? I am looking for an equivalent to the levels=cs2.levels keyword argument.
As you noted in a comment, your scatter and contour data are not directly related, but you want to display them on the same colormap.
I suggest setting a common colour span that contains both sets of data. Since obsData refers to the scatter points and areaData to the contours, I'd set
vmin,vmax = (fun(np.concatenate([obsData,areaData])) for fun in (np.min,np.max))
to determine the span of the collected data set (obviously, to be generalized for multiple input data sets). These can be passed to scatter and contourf to set the limits of the colour mapping:
cs = m[0].scatter(xs,ys,c=obsData,cmap=plt.cm.viridis,vmin=vmin,vmax=vmax)
cs2 = m[1].contourf(x,y,areaData,cmap=cs.cmap,vmin=vmin,vmax=vmax)
Some manual increase of the span might be in order to obtain a pretty result.
Note that I changed the colormap to viridis. If you really want to fairly represent your data, this should be your first step.
Which setting do I have to use to fit the ordinate axis position in the middle to the other two? The bigger y-axis scale moves it away sadly.
I am creating the graphs with:
plotting.gridplot(rows)
Where
rows.append(l)
with
l = line('x', 'y', source=datasource,
x_range=x_range[0], ...]
x_range[0] = l.x_range
for multiple 'y' in the datasource.
The graphs range is coupled via the x_range.
That's a bit hard to do at the moment, unfortunately. We are in the process of integrating cassowary.js for much better layout options of subplots, guides, annotations, etc. In the mean time, you can set the min_border (and min_border_left, min_border_top, etc) on your plots. This will make the border area a minimum size even if it could be smaller. So if you set it large enough to accommodate any labels you expect to see, then it should help make the plot sizes consistent.