My code:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors
x = y = np.linspace(0, 10, 51)
X, Y = np.meshgrid(x, y)
Z = X+Y # Z.min() => 0, Z.max() => 20
cf = plt.contourf(X, Y, Z,
levels=[5, 10, 15],
norm=colors.BoundaryNorm([5, 10, 15], 256, extend='both'))
cb = plt.colorbar(cf, extend='both')
plt.show()
Its output:
My expectations:
in the main plot, a dark blue lower triangle in place of the white one,
ditto, a bright yellow upper triangle,
the colorbar decorated with an upper bright yellow triangle and a lower dark blue triangle.
My question:
What have I done wrong?
As #JohanC notes, colorbar does strange things with a contour. However, in this simple case, why are you using BoundaryNorm?
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors
x = y = np.linspace(0, 10, 51)
X, Y = np.meshgrid(x, y)
Z = X+Y # Z.min() => 0, Z.max() => 20
cf = plt.contourf(X, Y, Z,
levels=[5, 10, 15], extend='both')
cb = plt.colorbar(cf, extend='both')
plt.show()
Does exactly what you want.
Related
I want to shade the area of the XY plane where Y<18 x^2.
This is my code:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-.25, .25, 25)
y = np.linspace(0, 1, 20)
X,Y = np.meshgrid(x, y)
Z = masqarr(1,X, Y)
plt.imshow( (Y< 18*X**2).astype(float) ,
extent=(X.min(),X.max(),Y.min(),Y.max()),origin="lower", cmap="Greys", alpha = 0.3, aspect='auto', interpolation = 'hanning');
However, the output I get produces a plot with plateau as in:
How can I gat a proper smooth plot?
This is a resolution problem, you are defining your axes with too few poitns. I tried this:
import numpy as np
import matplotlib.pyplot as plt
resolution = 200
x = np.linspace(-.25, .25, resolution)
y = np.linspace(0, 1, resolution)
X,Y = np.meshgrid(x, y)
plt.imshow( (Y< 18*X**2).astype(float) ,
extent=(X.min(),X.max(),Y.min(),Y.max()),origin="lower", cmap="Greys", alpha = 0.3, aspect='auto', interpolation = 'hanning');
plt.show()
resolution = 25
resolution = 100
resolution = 200
With the following code I have obtained the following contour map:
fig, ax = plt.subplots()
x = np.arange(431)
y = np.arange(225)
Y, X = np.meshgrid(y, x)
values = df["Appearance_percentage"].values
values2d = np.reshape(values, (431, 225))
ax.set_ylim(225, 0)
plt.style.use('seaborn-white')
ax.set_title('Mapa contour de probabilitat de trobar núvols')
plt.contour(X, Y, values2d, 30, cmap='RdGy')
plt.colorbar()
plt.savefig("contourmap.png")
I would like to know if I could fill the areas between the lines so that there are no white spaces in the color bar and the map is more attractive.
I tried doing df["Appearance_percentage_contourmap"] = round(df["Appearance_percentage"]) and then values = df["Appearance_percentage_contourmap"].values and I'm still obtaining the same map with lots of white areas.
Just replace plt.contour with plt.contourf, where the "f" at the end means "fill".
Here is an example:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(100)
y = np.arange(100)
Y, X = np.meshgrid(y, x)
values = np.outer(x, y)
fig, ax = plt.subplots()
plt.contourf(X, Y, values, 30, cmap='RdGy')
plt.colorbar()
You may also want to emphasis the contour lines with:
x = np.arange(100)
y = np.arange(100)
Y, X = np.meshgrid(y, x)
values = np.outer(x, y)
fig, ax = plt.subplots()
c1 = plt.contourf(X, Y, values, 30, cmap='RdGy')
c2 = plt.contour(X, Y, values, 30, cmap='Greys')
plt.colorbar(c1)
plt.contour() creates an isoline connecting all the places with an equal interpolated value. So, it searches places where the appearance is e.g. 6% and connects these with a line. If you set levels=30 there will be 30 such lines drawn. plt.contour() does a lot of effort to create a colorbar that shows the value for each line. If you don't want such a colorbar, you can create a custom colorbar using the same values.
You can create a custom colorbar as follows:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.cm import ScalarMappable
fig, ax = plt.subplots()
x = np.arange(431)
y = np.arange(225)
Y, X = np.meshgrid(y, x)
values = np.random.randn(431, 225).cumsum(axis=0).cumsum(axis=1).ravel()
values -= values.min()
values2d = np.reshape(values, (431, 225))
ax.set_ylim(225, 0)
plt.style.use('seaborn-white')
ax.set_title('Mapa contour de probabilitat de trobar núvols')
plt.contour(X, Y, values2d, 30, cmap='RdGy')
sm = ScalarMappable(norm=plt.Normalize(values.min(), values.max()), cmap='RdGy')
plt.colorbar(sm)
plt.show()
PS:Please don't round the values (as in df["Appearance_percentage_contourmap"] = round(df["Appearance_percentage"])), because that introduces artificial inaccuracies.
I am trying to draw 3 arrows over a surface using quiver. The arrows seem to always be draw behind the surface. This is the result:
And this is the code to generate this result:
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
def fun(x, y):
return x ** 2 - y ** 2
if __name__ == '__main__':
fig = plt.figure(dpi=160)
ax = fig.add_subplot(111, projection='3d')
x = y = np.arange(-3.0, 3.0, 0.05)
X, Y = np.meshgrid(x, y)
zs = np.array(fun(np.ravel(X), np.ravel(Y)))
Z = zs.reshape(X.shape)
ax.plot_surface(X, Y, Z, cmap=plt.get_cmap('Blues'))
ax.quiver([0], [0], [1], [0, -1, 0], [-1, 0, 0], [0, 0, 2.5], lw=4, color=['r', 'g', 'b']) # The z is 1 unit above the surface
ax.set_xlim3d(-3.5, 3.5)
ax.set_ylim3d(-3.5, 3.5)
ax.set_zlim3d(-8.5, 8.5)
plt.show()
How do I draw these arrows over a surface? I am using matplotlib 3.1.1, which is the latest version at the time of this question.
A hacky you solution you can use, while not ideal, is reduce the alpha of the surface.
ax.plot_surface(X, Y, Z, cmap=plt.get_cmap('Blues'), alpha=0.5)
I am trying to plot hatches over contours lines that
statisfy certian criteria folliwng the example found here. Yet, I got regular contours (the yellow lines) instead of the hatches. Any ideas how to resolve that. Thanks
import matplotlib.pyplot as plt
import numpy as np
# invent some numbers, turning the x and y arrays into simple
# 2d arrays, which make combining them together easier.
x = np.linspace(-3, 5, 150).reshape(1, -1)
y = np.linspace(-3, 5, 120).reshape(-1, 1)
z = np.cos(x) + np.sin(y)
# we no longer need x and y to be 2 dimensional, so flatten them.
x, y = x.flatten(), y.flatten()
fig2, ax2 = plt.subplots()
n_levels = 6
a=ax2.contourf(x, y, z, n_levels)
fig2.colorbar(a)
[m,n]=np.where(z > 0.5)
z1=np.zeros(z.shape)
z1[m,n]=99
cs = ax2.contour(x, y, z1,2,hatches=['','.'])
plt.show()enter code here
Use contourf() with proper parameters to get useful plot with hatching. See important comment within the working code below:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-3, 5, 150).reshape(1, -1)
y = np.linspace(-3, 5, 120).reshape(-1, 1)
z = np.cos(x) + np.sin(y)
x, y = x.flatten(), y.flatten()
fig2, ax2 = plt.subplots()
n_levels = 6
a = ax2.contourf(x, y, z, n_levels)
fig2.colorbar(a)
[m,n] = np.where(z > 0.5)
z1=np.zeros(z.shape)
z1[m, n] = 99
# use contourf() with proper hatch pattern and alpha value
cs = ax2.contourf(x, y, z1 ,3 , hatches=['', '..'], alpha=0.25)
plt.show()
The output plot:
I have 2d values of x and y which span from x - [ 1 , 5 ] and y - [0.1 - 0.5]
How can I plot the 3d surface where the axis are x , y and P(y) in matplotlib ?
I found out the code for doing so in matlab on net but I am unable to understand it and consequently convert it into matplotlib... ( the range of values is completely different for below written code as to what I require )
mu = [1 -1]; Sigma = [.9 .4; .4 .3];
[X1,X2] = meshgrid(linspace(-1,3,25)', linspace(-3,1,25)');
X = [X1(:) X2(:)];
p = mvnpdf(X, mu, Sigma);
surf(X1,X2,reshape(p,25,25));
Can someone help me out in doing the exact same thing for matplotlib ( plot_surface perhaps ? )
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.mlab as mlab
import numpy as np
def P(X, Y):
return mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
fig = plt.figure()
ax = fig.gca(projection = '3d')
jet = plt.get_cmap('jet')
x = np.linspace(-2, 2, 60)
y = np.linspace(-2, 2, 60)
X, Y = np.meshgrid(x, y)
Z = P(X, Y)
surf = ax.plot_surface(X, Y, Z, rstride = 1, cstride = 1, cmap = jet, linewidth = 0)
ax.set_zlim3d(0, Z.max())
plt.show()
yields