I have this meshplot that looks very clean in matlab for a 3d surface (Ignore the red border line):
And I am trying to emulate the same image in matplotlib. However, I get this weird shadow effect where the top of the surface is pure black and only the bottom is white:
I have the code for both plots here *my surface u can be replaced with any 3d data(ie peaks)
matlab
dx=0.01;
dt=0.001; %Attention : they have to be integer-multiples of one another
T=1.999; %length of simulation
x=(0:dx:1);
t=(0:dt:T);
u = load('u.mat', 'u');
u = u.u;
u2 = load('u2.mat','u');
u2 = u2.u;
pstep = 3;
tstep = 30;
xzeros = repelem(1, 1, length(t));
zline = interp2(x, t, u, xzeros, t);
zline2 = interp2(x, t, u2, xzeros, t);
subplot(1, 2, 1);
mesh(x(1:pstep:end),t(1:tstep:end),u(1:tstep:end,1:pstep:end), "edgecolor", "black");
view(90, 10);
xlabel('x', 'FontName', 'Arial', 'FontSize',18)
ylabel('Time', 'FontName', 'Arial', 'FontSize',18)
zlabel('u(x,t)', 'FontName', 'Arial', 'FontSize',18)
set(gca,'FontName', 'Arial', 'FontSize',18)
hold on
plot3(xzeros, t, zline, 'r', 'linewidth', 3);
subplot(1, 2, 2)
mesh(x(1:pstep:end),t(1:tstep:end),u2(1:tstep:end,1:pstep:end), "edgecolor", "black");
view(90, 10);
xlabel('x', 'FontName', 'Arial', 'FontSize',18)
ylabel('Time', 'FontName', 'Arial', 'FontSize',18)
zlabel('u(x,t)', 'FontName', 'Arial', 'FontSize',18)
set(gca,'FontName', 'Arial', 'FontSize',18)
hold on
plot3(xzeros, t, zline2, 'r', 'linewidth', 3);
set(gcf, 'PaperPositionMode', 'auto');
sgtitle("$$\hat{u}$ for PDE Solutions Using $\hat{k}$$", 'interpreter', 'latex', 'FontSize', 32)
saveas(gca, "matlab.png");
and matplotlib
fig = plt.figure(figsize=(8, 4))
plt.subplots_adjust(left=0.03, bottom=0, right=0.98, top=1, wspace=0.1, hspace=0)
subfigs = fig.subfigures(nrows=1, ncols=1, hspace=0)
subfig = subfigs
subfig.suptitle(r"$\hat{u}$ for PDE Solutions Using $\hat{k}$")
ax = subfig.subplots(nrows=1, ncols=2, subplot_kw={"projection": "3d"})
ax[0].plot_surface(x, t, uarr[0], edgecolor="black",lw=0.2, rstride=30,
cstride=3,
alpha=1, color="white")
ax[0].view_init(5, 5)
ax[0].set_xlabel("x", labelpad=10)
ax[0].set_ylabel("Time")
ax[0].set_zlabel(r"$\hat{u}(x, t)$", labelpad=5)
ax[0].zaxis.set_rotate_label(False)
ax[0].yaxis.set_major_formatter(FormatStrFormatter('%.1f'))
ax[1].plot_surface(x, t, uarr[2], edgecolor="black",lw=0.2, rstride=30,
cstride=3,
alpha=1,color="white")
ax[1].view_init(5, 5)
ax[1].set_xlabel("x", labelpad=10)
ax[1].set_ylabel("Time")
ax[1].set_zlabel(r"$\hat{u}(x, t)$", labelpad=5)
ax[1].zaxis.set_rotate_label(False)
ax[1].yaxis.set_major_formatter(FormatStrFormatter('%.1f'))
Any ideas on relieving this issue would be appreciated.
My guess is that you don't know the keyword argument
shade=...
, that by default is True
but it seems that you prefer no shading.
Here it is the (very simple) code that produces the graph above.
import numpy as np
import matplotlib.pyplot as plt
x = y = np.linspace(0, 10, 51)
x, y = np.meshgrid(x, y)
z = np.sin(y/7*x)
fig, ax = plt.subplots(1, 2,
figsize=(10, 5),
layout='tight',
subplot_kw=dict(projection="3d"))
ax[0].plot_surface(x, y, z, color='#F4FBFFFF', ec='black', lw=0.2, shade=True) # default
ax[1].plot_surface(x, y, z, color='#F4FBFFFF', ec='black', lw=0.2, shade=False)
plt.show()