当前位置: 首页 > 面试题库 >

如何为Matplotlib中的颜色栏设置动画

罗均
2023-03-14
问题内容

我有一个动画,其中数据范围变化很​​大。我想有一个colorbar跟踪数据的最大值和最小值(即我希望它不固定)。问题是如何做到这一点。

理想情况下,我希望colorbar该轴独立。

我尝试了以下四件事

1.天真的方法

问题:每帧都有一个新的彩条

#!/usr/bin/env python
"""
An animated image
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig = plt.figure()
ax = fig.add_subplot(111)


def f(x, y):
    return np.exp(x) + np.sin(y)

x = np.linspace(0, 1, 120)
y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)

frames = []

for i in range(10):
    x       += 1
    curVals  = f(x, y)
    vmax     = np.max(curVals)
    vmin     = np.min(curVals)
    levels   = np.linspace(vmin, vmax, 200, endpoint = True)
    frame    = ax.contourf(curVals, vmax=vmax, vmin=vmin, levels=levels)
    cbar     = fig.colorbar(frame)
    frames.append(frame.collections)

ani = animation.ArtistAnimation(fig, frames, blit=False)

plt.show()

2.添加到图像

将上面的for循环更改为

initFrame = ax.contourf(f(x,y)) 
cbar      = fig.colorbar(initFrame)
for i in range(10):
    x       += 1
    curVals  = f(x, y)
    vmax     = np.max(curVals)      
    vmin     = np.min(curVals)      
    levels   = np.linspace(vmin, vmax, 200, endpoint = True)
    frame    = ax.contourf(curVals, vmax=vmax, vmin=vmin, levels=levels)
    cbar.set_clim(vmin = vmin, vmax = vmax)
    cbar.draw_all()
    frames.append(frame.collections + [cbar])

问题:这引起了

AttributeError: 'Colorbar' object has no attribute 'set_visible'

3.在自己的轴上绘制

问题:colorbar尚未更新。

 #!/usr/bin/env python
 """
 An animated image
 """
 import numpy as np
 import matplotlib.pyplot as plt
 import matplotlib.animation as animation

 fig = plt.figure()
 ax1 = fig.add_subplot(121)
 ax2 = fig.add_subplot(122)


 def f(x, y):
     return np.exp(x) + np.sin(y)

 x = np.linspace(0, 1, 120)
 y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)

 frames = []

 for i in range(10):
     x       += 1
     curVals  = f(x, y)
     vmax     = np.max(curVals)
     vmin     = np.min(curVals)
     levels   = np.linspace(vmin, vmax, 200, endpoint = True)
     frame    = ax1.contourf(curVals, vmax=vmax, vmin=vmin, levels=levels)
     cbar     = fig.colorbar(frame, cax=ax2) # Colorbar does not update
     frames.append(frame.collections)

 ani = animation.ArtistAnimation(fig, frames, blit=False)

 plt.show()

2.和4.的组合

问题:colorbar常数。


问题答案:

虽然我不确定如何使用来具体实现ArtistAnimation,但使用还是FuncAnimation很简单的。如果我对您的“原始”版本1进行了以下修改,则可以正常工作。

修改版本1

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from mpl_toolkits.axes_grid1 import make_axes_locatable

fig = plt.figure()
ax = fig.add_subplot(111)

# I like to position my colorbars this way, but you don't have to
div = make_axes_locatable(ax)
cax = div.append_axes('right', '5%', '5%')

def f(x, y):
    return np.exp(x) + np.sin(y)

x = np.linspace(0, 1, 120)
y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)

frames = []
for i in range(10):
    x       += 1
    curVals  = f(x, y)
    frames.append(curVals)

cv0 = frames[0]
cf = ax.contourf(cv0, 200)
cb = fig.colorbar(cf, cax=cax)
tx = ax.set_title('Frame 0')

def animate(i):
    arr = frames[i]
    vmax     = np.max(arr)
    vmin     = np.min(arr)
    levels   = np.linspace(vmin, vmax, 200, endpoint = True)
    cf = ax.contourf(arr, vmax=vmax, vmin=vmin, levels=levels)
    cax.cla()
    fig.colorbar(cf, cax=cax)
    tx.set_text('Frame {0}'.format(i))

ani = animation.FuncAnimation(fig, animate, frames=10)

plt.show()

主要区别在于,我在函数中执行关卡计算和轮廓绘制,而不是创建艺术家列表。由于您可以清除上一帧中的轴并在每帧中重做轴,因此色条起作用。

使用contour或时contourf,必须重做,因为您不能只是动态地更改数据。但是,当您绘制了许多轮廓线并且结果看起来很平滑时,我认为最好imshow改用它-
这意味着您实际上可以只使用同一位艺术家并更改数据,并且颜色栏会自动更新。它也快得多!

更好的版本

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from mpl_toolkits.axes_grid1 import make_axes_locatable

fig = plt.figure()
ax = fig.add_subplot(111)

# I like to position my colorbars this way, but you don't have to
div = make_axes_locatable(ax)
cax = div.append_axes('right', '5%', '5%')

def f(x, y):
    return np.exp(x) + np.sin(y)

x = np.linspace(0, 1, 120)
y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)

# This is now a list of arrays rather than a list of artists
frames = []
for i in range(10):
    x       += 1
    curVals  = f(x, y)
    frames.append(curVals)

cv0 = frames[0]
im = ax.imshow(cv0, origin='lower') # Here make an AxesImage rather than contour
cb = fig.colorbar(im, cax=cax)
tx = ax.set_title('Frame 0')

def animate(i):
    arr = frames[i]
    vmax     = np.max(arr)
    vmin     = np.min(arr)
    im.set_data(arr)
    im.set_clim(vmin, vmax)
    tx.set_text('Frame {0}'.format(i))
    # In this version you don't have to do anything to the colorbar,
    # it updates itself when the mappable it watches (im) changes

ani = animation.FuncAnimation(fig, animate, frames=10)

plt.show()


 类似资料:
  • 问题内容: 我有以下代码: 因此,这将使用指定的颜色图在X轴和Y轴上生成值的图形。和轴是完美的,但是颜色图在的最小值和最大值之间分布。我想强制颜色图的范围在0到1之间。 我想到使用: 设置轴的范围,但这仅接受X和Y的最小值和最大值的参数,而不是颜色图。 编辑: 为了清楚起见,假设我有一个图的值的范围为(0 … 0.3),而另一个图的值的范围为(0.2 … 0.8)。 在两个图中,我都希望颜色条的范

  • 问题内容: 特别是在处理灰度图像时,将每个命令的色图设置为会很麻烦。如何设置matplotlib使用的默认颜色图来灰度或其他颜色图? 问题答案: 要仅为当前交互式会话或一个脚本更改默认颜色图,请使用 对于2.0之前的版本,您必须使用rcParams字典。在新版本中仍然有效。 要更改默认颜色图,请永久编辑matplotlibrc配置文件并添加该行。根据需要,将灰色值替换为任何其他有效的颜色图。配置文

  • 因此,我有一段代码,它以我需要的格式愉快地显示了一个图形: 我想让图表中的一个条显示为不同于上面代码中设置的颜色。

  • 我花了太长时间研究如何在Matplotlib中使两个子图共享同一y轴,并在两个子图之间共享一个颜色条。 所发生的事情是,当我在或中调用函数时,它会自动缩放绘图,这样colorbar加上绘图就可以放在“subplot”边界框中,导致两个并排绘图的大小非常不同。 为了解决这个问题,我试图创建第三个子情节,然后我黑客攻击它,使其不呈现仅有颜色条的情节。唯一的问题是,现在两个地块的高度和宽度都不均匀,我想