I have a question regarding the colorbar of the matplotlib. I have a surface-plot, which is working fine, and the colors are used correctly. But somehow, the scale of my colorbar is messed up. I think it should go from 0 to 0.4. But the actual code gives me 0 to 0.16. What am I missing here? Strange that the value 0.16 is the square of 0.4.
Here is my plot:
And of course, here is my code:
values_all = zip(*values_all)
x = range(len(values_all[0]))
y = range(len(values_all))
figure = plt.figure(1, figsize=(10, 7))
ax = Axes3D(figure, azim=-124, elev=40, zlim=(0, 0.4))
x, y = np.meshgrid(x, y)
surface = ax.plot_surface(x, y, values_all, linewidth=0, rstride=1, cstride=1, cmap=cm.jet)
plt.colorbar(surface, shrink=0.4, aspect=10)
plt.show()
If I edit my code the following way, the colorbar is scaled correctly, but the plot itself is not colored correctly anymore:
surface = ax.plot_surface(x, y, values_all, linewidth=0, rstride=1, cstride=1, cmap=cm.jet,vmin=0,vmax=0.4)
Results in:
With other sample data, you can see that this is not only an issue of the plot's borders (The values that are giving the strange peak are between 0.3-0.35):
Related
I have this set of data, which I would like to plot it in a 3D surface and in a contour by using python (numpy and matplotlib, basically). In this case, I have the X and Y axis as my free coordinates, and the results are described as a dataset on the z-axis.
I've checked many times the data, and it is formatted correctly to my needs.
Here is a plot of the set in a scatter manner
The problem is when I try to use the surface plot, where the end points of the (X, Y) mesh are connected, closing the surface and making not visible the part of the image that contains the information I would like to have. Here is the output I have regarding the surface plot and here is the output regarding the contour plot.
The code related to the surface plot (only ploting part) is
#...
#X and Y are the coordinates values
#E is the results I am trying to plot
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(X, Y, E, cmap=cm.coolwarm, linewidth=0, antialiased=False)
ax.scatter3D(X, Y, E, cmap='Greens')
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
Here is the code related to the contour plot
fig, ax = plt.subplots()
CS = ax.contourf(X, Y, E, 10, cmap='RdGy')
ax.clabel(CS, inline=1, fontsize=10)
ax.set_title('Simplest default with labels')
fig.colorbar(CS, shrink=0.5, aspect=5)
plt.show()
Why will my surface plot colour change from the 1st to the second in terms of colour?
The following is my code for the plot:
def Plots3d(U):
fig = plt.figure()
ax = fig.gca(projection='3d')
y, x = U.shape
Y = np.arange(0, y, 1)
X = np.arange(0, x, 1)
Y, X = np.meshgrid(Y, X)
Z = U[Y, X]
ax.plot_surface(X, Y, Z, rstride=1, cstride=1,
linewidth=0.7, antialiased=False, cmap = cm.summer)
plt.xlabel('Stock Price Nodes')
plt.ylabel('Timesteps')
plt.title('Analytical solution surface for 0 <= t <= 2')
plt.show()
This looks like a resolution problem: the lines in the saved plot are too thick and are dominating the figure when saved, turning it black. The default resolution of a saved figure and a figure produced with plt.show are probably different in your matplotlibrc file.
You could try either increasing the resolution (the dots per square inch, or dpi) or decreasing the linewidth.
A few possible options for you:
Increase dpi with rcParams
from matplotlib import rcParams
# this changes the dpi of figures saved from plt.show()
rcParams['figure.dpi'] = 300
# this changes the dpi of figures saved from plt.savefig()
rcParams['savefig.dpi'] = 300
Increase dpi during savefig
If you don't want to use rcParams, you can just increase the dpi as you save the figure:
plt.savefig('myfigure.png', dpi=300)
Decreasing linewidth
Alternatively, you could try decreasing the linewidth of the surface plot
ax.plot_surface(X, Y, Z, rstride=1, cstride=1,
linewidth=0.3, antialiased=False, cmap = cm.summer)
I have setup mplot3d to provide a 3D surface plot per the example.
When I plot my data I am seeing that the surface is missing from a ridge running through the surface (see image). I noticed that surface filling appears to follow the stride but the grid-lines make viewing difficult at lower step sizes.
from mpl_toolkits.mplot3d import axes3d
from matplotlib import cm, pyplot
import numpy
Z = data[-300::]
X,Y = numpy.mgrid[:len(Z), :len(Z[0])]
fig = pyplot.figure(figsize=(20, 10), dpi=800)
ax = fig.gca(projection='3d')
surf = ax.plot_surface(X,
Y,
Z,
rstride=len(Z)/5,
cstride=len(Z[0])/10,
alpha=.6,
linewidths=(.5,),
antialiased=True,
cmap=cm.coolwarm,
vmin=124,
vmax=186
)
cset = ax.contourf(X, Y, Z, zdir='z', offset=130, cmap=cm.coolwarm, vmin=124, vmax=186)
ax.set_xlim(len(Z) * 1.2, 0)
ax.set_ylim(0, len(Z[0]) * 1.2)
ax.elev = 25
ax.azim = 20
cb = fig.colorbar(surf, shrink=0.5, aspect=5)
Is there a way to fill the missing surface?
The only way i have found to accomplish this is by setting the stride to one and linewidth to 0. The downside to this is that I appear to lose the grid overlay.
surf = ax.plot_surface(X,
Y,
Z,
shade=True,
rstride=1, cstride=1, linewidth=0,
linewidths=(.5,),
antialiased=True,
)
I have a surface plot, and I need this specific point of view that I have chosen. See the image below:
Now, as you can see, the very bottom part of my axis legend is missing, because matplotlib is cutting it off. Is there any way to programmatically zoom out of the plot so everything fits in the window?
This is my original code:
values_all = zip(*values_all)
x = range(len(values_all[0]))
y = range(len(values_all))
figure = plt.figure(1, figsize=(10, 7))
ax = Axes3D(figure, azim=-124, elev=40, zlim=(0, 0.4))
x, y = np.meshgrid(x, y)
surface = ax.plot_surface(x, y, values_all, linewidth=0, rstride=1, cstride=1, cmap=cm.jet)
plt.colorbar(surface, shrink=0.4, aspect=10)
plt.show()
Call
plt.tight_layout()
before
plt.show()
I am trying to make a grid on the surface of my surfaceplot, now I know that wireframe does not work and the grid command is something else entirely. But how do you plot things with grids like this?
Here is the plot command I am using
fig = plt.figure()
ax = fig.add_subplot(111,projection="3d")
plot = ax.plot_surface(x,y,z, rstride=1, cstride=1, cmap=cm.jet, shade=True,
linewidth=0, antialiased=False)
From the (second) example in the matplotlib surface plot documentation, from which the image in the OP comes from (see the source code here), it is clear that the plot_surface function draws grid lines on surface plots by default. However, the plotting command
plot = ax.plot_surface(x,y,z, rstride=1, cstride=1, cmap=cm.jet, shade=True,
linewidth=0, antialiased=False)
sets the width of the grid lines to zero, so they are not visible, but are present, when using this call. Remove the linewidth=0 argument or set this to a value greater than 0.