设置固定的颜色条值
setting fixed color bar values
我正在绘制一些按时间步长设置动画的节点数据,如下所示:
fig, ax = plt.subplots()
fig.tight_layout()
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
def animate(i):
ax.cla()
plt.cla()
ax.set_aspect('equal', 'box')
c = ax.tricontourf(triang, z[:, i], 10, cmap='plasma')
c.set_clim(np.min(z), np.max(z))
plt.colorbar(c, cax=cax)
anim = FuncAnimation(fig, animate, interval=100, frames=nt)
其中 z - 是 nnodes x number_of_timesteps
节点值矩阵。但是正如您在下图中看到的那样,颜色条的范围和值似乎并不固定。我的意思是分配给特定颜色的值似乎是固定的,但颜色图例是随时间变化的。我认为 c.set_clim(np.min(z), np.max(z))
应该修复它,因为它在每个时间步都从整个数据集中获取最小和最大节点值,但显然它没有修复颜色条。有办法解决吗?
@SKPS,我们开始吧。在下面的脚本中,我使用了坐标的假函数,只是为了给你一些值,因为原始的是基于 FEM 例程的,因此它非常庞大。使用提供的 link,您可以下载脚本中使用的网格文件。在下面的代码中,我尝试了两种方式:FuncAnimation
,用于 animate_plot()
和 ArtistAnimation
,用于 animate_plot2()
。您可以通过编辑代码的最后一行在它们之间切换。看,已经描述了 FuncAnimation
的问题。使用ArtistAnimation
时,colorbar看起来是静态的,但实际上是最后一个时间步的colorbar。为了演示它,我更改了 animate_plot2()
中的绘图函数,所以如果你 运行 它,你就会明白我的意思。同样在这种情况下,您会看到绘图的标题不再更新 - 它始终显示一个值。我试图通过添加行 ax.cla()
和 plt.cla()
来修复它,就像以前的情况一样,但它搞砸了更多。
亲切的问候。
网格:
https://www.dropbox.com/s/x4njq0t93636wfv/new_cave.msh?dl=0
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.tri as mtri
import meshio
from matplotlib.animation import FuncAnimation
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib.offsetbox import (AnchoredOffsetbox, DrawingArea, HPacker,
TextArea)
def load_mesh(mesh_filename):
m = meshio.read(mesh_filename)
p = m.points.transpose()
p = np.delete(p, 2, axis=0)
t = m.cells["triangle"]
return p, t
def animate_plot(nt, p, t):
x = p[0, :]
y = p[1, :]
triang = mtri.Triangulation(x, y, t)
nnodes = len(p[0])
z = np.zeros((nnodes, nt))
for j in range(nt):
z[:, j] = j ** 2 * (np.sin(x * 10) + np.sin(y * 10))
fig, ax = plt.subplots()
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
def animate(i):
ax.cla()
plt.cla()
ax.set_aspect('equal', 'box')
ax.set(xlim=(min(x), max(x)), ylim=(min(y), max(y)))
c = ax.tricontourf(triang, z[:, i], 10, cmap='plasma', vmin=-1, vmax=1)
c.set_clim(np.min(z), np.max(z))
ax.triplot(triang, color='white', lw=0.1)
ax.set_title('test, ' + 'np.min(z)=' + str(np.min(z)) + ', np.max(z)=' + str(np.max(z)) + '.')
cbar = plt.colorbar(c, cax=cax, format='%.0e')
ax.set_xlabel('x [m]')
ax.set_ylabel('y [m]')
anim = FuncAnimation(
fig, animate, interval=600, frames=nt)
anim.save('test.gif', writer='imagemagick')
def animate_plot2(nt, p, t):
x = p[0, :]
y = p[1, :]
triang = mtri.Triangulation(x, y, t)
nnodes = len(p[0])
z = np.zeros((nnodes, nt))
for j in range(nt):
z[:, j] = 100 * (np.sin(x * 10) + np.sin(y * 10)) - j ** 2 * (np.sin(x * 10) + np.sin(y * 10))
img = []
fig, ax = plt.subplots()
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
for i in range(nt):
# ax.cla()
# plt.cla()
ax.set_aspect('equal', 'box')
ax.set(xlim=(min(x), max(x)), ylim=(min(y), max(y)))
fig.tight_layout()
ax.set_title('time step = ' + str(i))
c = ax.tricontourf(triang, z[:, i], 10, cmap='plasma')
c.set_clim(np.min(z), np.max(z))
ax.triplot(triang, color='white', lw=0.1)
plt.colorbar(c, cax=cax)
img.append(c.collections)
name = 'test.gif'
anim_img = animation.ArtistAnimation(fig, img, interval=300, blit=True)
anim_img.save(name, writer='imagemagick', bitrate=300)
mesh_filename = 'new_cave.msh'
p, t = load_mesh(mesh_filename)
nt = 10
animate_plot2(nt, p, t)
你每次都得到不同的颜色条,因为你没有指定你的轮廓水平。尝试:
c = ax.tricontourf(triang, z[:, i], 10, cmap='plasma', vmin=-1, vmax=1, levels=np.arange(-1, 1.02, 0.1))
我正在绘制一些按时间步长设置动画的节点数据,如下所示:
fig, ax = plt.subplots()
fig.tight_layout()
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
def animate(i):
ax.cla()
plt.cla()
ax.set_aspect('equal', 'box')
c = ax.tricontourf(triang, z[:, i], 10, cmap='plasma')
c.set_clim(np.min(z), np.max(z))
plt.colorbar(c, cax=cax)
anim = FuncAnimation(fig, animate, interval=100, frames=nt)
其中 z - 是 nnodes x number_of_timesteps
节点值矩阵。但是正如您在下图中看到的那样,颜色条的范围和值似乎并不固定。我的意思是分配给特定颜色的值似乎是固定的,但颜色图例是随时间变化的。我认为 c.set_clim(np.min(z), np.max(z))
应该修复它,因为它在每个时间步都从整个数据集中获取最小和最大节点值,但显然它没有修复颜色条。有办法解决吗?
@SKPS,我们开始吧。在下面的脚本中,我使用了坐标的假函数,只是为了给你一些值,因为原始的是基于 FEM 例程的,因此它非常庞大。使用提供的 link,您可以下载脚本中使用的网格文件。在下面的代码中,我尝试了两种方式:FuncAnimation
,用于 animate_plot()
和 ArtistAnimation
,用于 animate_plot2()
。您可以通过编辑代码的最后一行在它们之间切换。看,已经描述了 FuncAnimation
的问题。使用ArtistAnimation
时,colorbar看起来是静态的,但实际上是最后一个时间步的colorbar。为了演示它,我更改了 animate_plot2()
中的绘图函数,所以如果你 运行 它,你就会明白我的意思。同样在这种情况下,您会看到绘图的标题不再更新 - 它始终显示一个值。我试图通过添加行 ax.cla()
和 plt.cla()
来修复它,就像以前的情况一样,但它搞砸了更多。
亲切的问候。
网格: https://www.dropbox.com/s/x4njq0t93636wfv/new_cave.msh?dl=0
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.tri as mtri
import meshio
from matplotlib.animation import FuncAnimation
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib.offsetbox import (AnchoredOffsetbox, DrawingArea, HPacker,
TextArea)
def load_mesh(mesh_filename):
m = meshio.read(mesh_filename)
p = m.points.transpose()
p = np.delete(p, 2, axis=0)
t = m.cells["triangle"]
return p, t
def animate_plot(nt, p, t):
x = p[0, :]
y = p[1, :]
triang = mtri.Triangulation(x, y, t)
nnodes = len(p[0])
z = np.zeros((nnodes, nt))
for j in range(nt):
z[:, j] = j ** 2 * (np.sin(x * 10) + np.sin(y * 10))
fig, ax = plt.subplots()
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
def animate(i):
ax.cla()
plt.cla()
ax.set_aspect('equal', 'box')
ax.set(xlim=(min(x), max(x)), ylim=(min(y), max(y)))
c = ax.tricontourf(triang, z[:, i], 10, cmap='plasma', vmin=-1, vmax=1)
c.set_clim(np.min(z), np.max(z))
ax.triplot(triang, color='white', lw=0.1)
ax.set_title('test, ' + 'np.min(z)=' + str(np.min(z)) + ', np.max(z)=' + str(np.max(z)) + '.')
cbar = plt.colorbar(c, cax=cax, format='%.0e')
ax.set_xlabel('x [m]')
ax.set_ylabel('y [m]')
anim = FuncAnimation(
fig, animate, interval=600, frames=nt)
anim.save('test.gif', writer='imagemagick')
def animate_plot2(nt, p, t):
x = p[0, :]
y = p[1, :]
triang = mtri.Triangulation(x, y, t)
nnodes = len(p[0])
z = np.zeros((nnodes, nt))
for j in range(nt):
z[:, j] = 100 * (np.sin(x * 10) + np.sin(y * 10)) - j ** 2 * (np.sin(x * 10) + np.sin(y * 10))
img = []
fig, ax = plt.subplots()
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
for i in range(nt):
# ax.cla()
# plt.cla()
ax.set_aspect('equal', 'box')
ax.set(xlim=(min(x), max(x)), ylim=(min(y), max(y)))
fig.tight_layout()
ax.set_title('time step = ' + str(i))
c = ax.tricontourf(triang, z[:, i], 10, cmap='plasma')
c.set_clim(np.min(z), np.max(z))
ax.triplot(triang, color='white', lw=0.1)
plt.colorbar(c, cax=cax)
img.append(c.collections)
name = 'test.gif'
anim_img = animation.ArtistAnimation(fig, img, interval=300, blit=True)
anim_img.save(name, writer='imagemagick', bitrate=300)
mesh_filename = 'new_cave.msh'
p, t = load_mesh(mesh_filename)
nt = 10
animate_plot2(nt, p, t)
你每次都得到不同的颜色条,因为你没有指定你的轮廓水平。尝试:
c = ax.tricontourf(triang, z[:, i], 10, cmap='plasma', vmin=-1, vmax=1, levels=np.arange(-1, 1.02, 0.1))