I plotted a 2 sigma C.L ellipse using contour plot function in matplotlib. However I am unable to fill it with colours. Only the boundaries are coloured.
plt.contour(x, y, likelihood, [level1,level2])
Where x=[100,], y=[100,] and l=[100,100] dimensional arrays. The plot I get is as shown below : I would like the ellipses to be of solid colour. How to do it ? using cmap doesnt help either as posted in some other threads in this forum.
Thanks to #kwinkunks here is a solution
plt.contourf(x, y, likelihood, [level1,level2],colors=['white', 'grey', 'red'],extend='both')
Related
I try to make simple 3D plot with plot_surface of matplotlib, below is the minimum example:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
x_test = np.arange(0.001, 0.01, 0.0005)
y_test = np.arange(0.1, 100, 0.05)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
Xtest, Ytest = np.meshgrid(x_test, y_test)
Ztest = Xtest**-1 + Ytest
surf = ax.plot_surface(Xtest, Ytest, Ztest,
cmap=cm.plasma, alpha=1,
antialiased=False)
fig.colorbar(surf, shrink=0.5, aspect=5)
ax.set_ylabel(r'$ Y $', fontsize=16)
ax.set_xlabel(r'$ X $', fontsize=16)
ax.set_zlabel(r'$ Z $', fontsize=16)
The result gives strange colormap, that does not represent the magnitude of the z scale, as you can see from here 3D plot result.
I mean if you take a straight line of constant Z, you don't see the same color.
I've tried to change the ccount and rcount inside plot_surface function or changing the interval of the Xtest or Ytest data, nothing helps.
I've tried some suggestion from here and here. But it seems not related.
Could you help me how to solve this? It seems a simple problem, but I couldn't solve it.
Thanks!
Edit
I add example but using the original equation that I don't write it here (it's complicated), please take a look: Comparison.
While the left figure was done in Matlab (by my advisor),
the right figure by using matplotlib.
You can see clearly the plot on the left really make sense,
the brightest color always on the maximum z-axis. Unfortunately, i don't know matlab. I hope i can do it by using python,
Hopefully this edit makes it more clear of the problem.
Edit 2
I'm sure this is not the best solution. That's why I put it here, not as an answer. As suggested by #swatchai to use the contour3D.
Since surface is set of lines, I can generate the correct result by plotting a lot of contour lines, by using:
surf = ax.contour3D(Xtest, Ytest, Ztest, 500, cmap=cm.plasma,
alpha=0.5, antialiased=False)
The colormap is correct as you can see from herealternative1
But the plot is very heavy. When you zoom-in, it doesn't look good, unless you increase again the number of the contour.
Any suggestion are welcome :).
I don't know how this can be achieved but maybe some words on why this is happening.
plot_surface generates a mesh where the vertices are defined by x and y and z.
Each patch has 4 corners and gets a color corresponding to its z value. Looking at the plot it
could be the maximal z value of the 4 corners (just a guess).
And if you look closely the colors of the patches actually do get lighter as you move in +y direction.
But what is far more obvious are the color changes in x direction, producing the slopes you mentioned.
But this can not be avoided if each patch has just a single color.
You can see this maybe more clearly if you change the formula to Z = (X**-1 + 10 * Y)
The behavior of the surface plot is not what you expect. Only contour3D or contourf3D can display such behavior. Here is relevant code that you can try to get the plot that follows:
surf = ax.plot_surface(Xtest, Ytest, Ztest, cmap=cm.plasma, alpha=0.55)
ax.contourf3D(Xtest, Ytest, Ztest, cmap=cm.plasma)
The plot that show both surface and contourf3D:
I guess, the formal answer to plot this kind of surface is by using Axes3D.contour and Axes3D.contourf. Based on documentation
, for example:
surf2 = ax.contourf(Xtest, Ytest, Ztest, 250, cmap=cm.plasma,
alpha=0.6, antialiased=False)
surf = ax.contour(Xtest, Ytest, Ztest, 250, cmap=cm.plasma,
alpha=0.6, antialiased=False)
The result is here. The colormap shows correct z-scale.
It's not as perfect as smooth surface, as it depends on how much we zoom it or how much we put the contour. I don't know if there's a way to create this by plot_surface. thanks #swatchai.
I'm trying to plot a line through a 3-D surface as a means of indicating the axis. However, this only results in the line being plotted entirely on top of or beneath the surface--changing the zorder does not solve this.
What I'm looking for is for the line to appear as if it were piercing through the surface
My code and output are below:
fig = plt.figure(figsize=(9,9))
ax = plt.axes(projection='3d')
ax.plot_surface(X,Z,Y,
linewidth=0,
cmap=cm.jet,
facecolors=cm.jet(r_3d/max(abs(r_3d.flatten()))),
edgecolor='none',
shade=False,
antialiased=False)
ax.plot([0,0],[-0.3,0.3],[0,0],linewidth=2,c='k')
Example of line plotted on top of surface
Hand drawn example of my desired output
I think you can solve this with zorder (example here), though I have not tried specifically with a 3d plot. zorder changes the plotting order, or essentially the depth at which specific items are plotted. Large z orders plot on top and small ones plot in the back, so if you make the 3d item a z order of 1 and the line as z order zero that should work.
I have several thousand points with X,Y,C values (in numpy arrays).
I want each X,Y point to be plotted on a 2D image plot with a colored square around it (a box of size 40x40 units). Each X,Y point should be centered in the middle of the box. The colour of the box will be mapped according to the C value. The X,Y points are fairly randomly spaced. The points are arranged so that no boxes will overlap, they may touch, or have gaps.
I'm not a Python expert so would appreciate if someone could help get me started on this with a few lines of code. I believe that something like imshow or pcolor will be needed.
Thanks,
You can simply set up the size and marker type in the scatter command.
That'd be my solution:
X = 50 * np.round(10 * np.random.rand(100))
Y = 50 * np.round(10 * np.random.rand(100))
C = np.random.rand(100)
plt.figure(figsize=(12, 12))
sc = plt.scatter(X, Y, s=40**2, c=C, marker='s', cmap='gist_rainbow')
plt.scatter(X, Y, s=11**2, c='k')
plt.colorbar(sc)
plt.axis('equal')
plt.show()
The output would be the following:
Hope that helps!
I have to make the following scatterplot in python. The code for this plot is :
n = 1024
X = np.random.normal(0,1,n)
Y = np.random.normal(0,1,n)
plt.scatter(X,Y)
But as espected, this wont give the colours. I've tried a lot, but can't find the solution. I know it has something to do with the angle of X/Y in the plot, but can't find out how to do this.
The logic is most likely angle from origo to point. This can be calculated easily with np.arctan2(X, Y). I don't know which colormap that is used in your example but you can probably find it here: https://matplotlib.org/examples/color/colormaps_reference.html
Use the angles of the points to the c keyword in plt.scatter
To get something similar to your example:
plt.scatter(X,Y, c=np.arctan2(X, Y), cmap='rainbow', s=50, alpha=0.8)
I have an array A which I have plotted in a contour plot using X and Y as coordinate axes,
plt.contourf(X,Y,A)
Problem is, the values in A vary from 1 to a very large number such that the color scale doesn't show a plot. When I plot log(A), I get the following contour,
which is what I'm looking for. But I want to be able to view the values of the array A, instead of log(A), when I hover my cursor over a certain (X,Y) point. I already got an answer for how to do that, but how would I go about doing it while my colour scale remains log? Basically what I'm trying to do is to make the color scale follow a log pattern, but not the array values themselves.
Thanks a lot!
You can do this:
from matplotlib import colors
plt.contourf(X, Y, A, norm=colors.LogNorm())
plt.colorbar()
plt.show()
or
from matplotlib import ticker
plt.contourf(X, Y, A, locator=ticker.LogLocator())
plt.colorbar()
plt.show()
A similar question was already asked for log-scaling the colors in a scatter plot: A logarithmic colorbar in matplotlib scatter plot
As is it was indicated there, there is an article in matplotlibs documentation that describes norms of colormaps: http://matplotlib.org/devdocs/users/colormapnorms.html
Essentially, you can set the norm of your contourplot by adding the keyword , norm=matplotlib.colors.LogNorm()