Set separation between ticks when using log scale on matplotlib - python

This is the chart I did in 3D using Google Sheets.
I want to achieve the same scale on matplotlib but using a 3D surface.
The problem is that the ticks on logscale are being placed where they "should be" if it was a normal scale.
Here is my code:
X, Y = np.meshgrid(numrec, numtreino)
Z = (numerador/(((rec[0])+(treino[0]*60))/((rec[1])+(treino[1]*60))))*X
# Plot the surface.
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm,
linewidth=2, antialiased=True, alpha=0.8)
ax.set_xscale('symlog')
ax.set_yscale('symlog')
ax.invert_xaxis()
# Add a color bar which maps values to colors.
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()

As pointed out by ImportanceOfBeingErnest, it seems to be a bug in matplotlib.
If you enable a log scale when doing a 3D scatter plot, nothing is created and the program crashes.
Instead of ax.set_xscale('log'), ax.set_xscale('symlog') should be used.
To fix the scaling problem I've changed:
Z = (numerador/(((rec[0])+(treino[0]*60))/((rec[1])+(treino[1]*60))))*X
# Plot the surface.
to:
Z = (numerador/(((rec[0])+(treino[0]*60))/((rec[1])+(treino[1]*60))))*X
X = np.log10(X)
Y = np.log10(Y)
# Plot the surface.
To set the ticks I've added:
zticks = [ 1e3, 1e2, 1e1]
ax.set_xticks(np.log10(zticks))
ax.set_xticklabels(zticks)

Related

How to make 3d plot with matplotlib and rectangular grid shape?

I'm trying to create a 3d plot using matplot lib with some data taken from rectangular surface. Coordinates of all measurments are saved on two lists processed by np.meshgrid. The problem is matplotlib ax.plot_srface() seems to accept only square grid (then it works). Is there any way to force matplotlib to work with rectangular shape or append mesh to be square? Code and error are below:
def graph3d(a_div, b_div, res):
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
side_div=get_side(b_div, res)
print(f"{a_div}\n\n{side_div}")
X, Y = np.meshgrid(a_div, side_div)
z = random_test(X, Y)
surf = ax.plot_surface(X, Y, z, cmap=cm.hsv, linewidth=0, antialiased=False)
ax.set_zlim(-2.5, 2.5)
ax.set_title("Measurement results 3D plot")
ax.zaxis.set_major_locator(LinearLocator(10))
# A StrMethodFormatter is used automatically
ax.zaxis.set_major_formatter('{x:.02f}')
# Add a color bar which maps values to colors.
fig.colorbar(surf, shrink=3, aspect=5)
plt.show()
raise TypeError('Dimensions of C %s are incompatible with'
TypeError: Dimensions of C (21, 2) are incompatible with X (21) and/or Y (2); see help(pcolor)

End points of 3D surface being connected

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

Color of surface plots turning black after saving- Python

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)

Zoom out in Matplotlib

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

Python colorbar scale

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

Categories

Resources