循环绘制海上漂移点时如何不保留历史绘制点?
解决Basemap绘制海上漂移点时叠加历史点的问题
看起来你遇到的问题是:在循环绘制逐小时的漂移点时,所有历史时刻的点都会保留在图上,而不是只显示当前时刻的点(或者只显示到当前时刻的轨迹+高亮当前点)。这是因为matplotlib默认会把每次绘图的内容叠加在同一个坐标轴上,不会自动清除之前的元素。
下面给你几种不同场景的解决方案,你可以根据自己的需求选择:
方案1:逐帧清除重绘(简单直观)
如果只是想快速实现“每小时更新一次,只显示当前时刻的点”,可以在每次循环里先清除当前轴的内容,再重新绘制底图和当前点:
import matplotlib.pyplot as plt from mpl_toolkits.basemap import Basemap import numpy as np # 替换成你自己的真实数据 Duration = 6 # hours Xpos1 = np.linspace(-4.5, -3.5, Duration) # 模拟经度数据 Ypos1 = np.linspace(51.0, 51.5, Duration) # 模拟纬度数据 plt.figure(figsize=(20, 10)) # 只初始化一次Basemap,避免重复创建开销 map = Basemap( width=300000, height=300000, projection='lcc', resolution='c', lat_0=51.25, lon_0=-4 ) for i in range(Duration): # 清除当前轴的所有内容,保留画布和Basemap设置 plt.cla() # 重新绘制底图元素 map.drawmapboundary(fill_color='turquoise') map.fillcontinents(color='white', lake_color='aqua') map.drawcountries(linestyle='--') # 转换当前时刻的经纬度到地图投影坐标 x, y = map(Xpos1[i], Ypos1[i]) # 绘制当前点(红色圆点,大小10) map.plot(x, y, 'ro', markersize=10) # 添加时刻标题 plt.title(f"海上漂移位置 - 第{i+1}小时") # 暂停0.5秒让画面显示出来,可根据需要调整 plt.pause(0.5) # 最后显示最终画面 plt.show()
方案2:保留轨迹+高亮当前点
如果想同时显示到当前时刻的漂移轨迹,并且高亮当前点,可以修改成这样:
import matplotlib.pyplot as plt from mpl_toolkits.basemap import Basemap import numpy as np Duration = 6 # hours Xpos1 = np.linspace(-4.5, -3.5, Duration) Ypos1 = np.linspace(51.0, 51.5, Duration) plt.figure(figsize=(20, 10)) map = Basemap( width=300000, height=300000, projection='lcc', resolution='c', lat_0=51.25, lon_0=-4 ) for i in range(Duration): plt.cla() # 重绘底图 map.drawmapboundary(fill_color='turquoise') map.fillcontinents(color='white', lake_color='aqua') map.drawcountries(linestyle='--') # 绘制到当前时刻的所有轨迹点(浅蓝色,半透明) x_history, y_history = map(Xpos1[:i+1], Ypos1[:i+1]) map.plot(x_history, y_history, 'bo', markersize=5, alpha=0.5) # 绘制当前点(红色,更大更醒目) x_current, y_current = map(Xpos1[i], Ypos1[i]) map.plot(x_current, y_current, 'ro', markersize=12) plt.title(f"海上漂移轨迹 - 第{i+1}小时") plt.pause(0.5) plt.show()
方案3:用动画模块高效实现(推荐做流畅动画)
如果想要更流畅的动画效果,并且避免每次重绘底图的开销,推荐使用matplotlib的FuncAnimation模块,只更新需要变化的元素:
import matplotlib.pyplot as plt from mpl_toolkits.basemap import Basemap import numpy as np from matplotlib.animation import FuncAnimation Duration = 6 # hours Xpos1 = np.linspace(-4.5, -3.5, Duration) Ypos1 = np.linspace(51.0, 51.5, Duration) fig = plt.figure(figsize=(20, 10)) map = Basemap( width=300000, height=300000, projection='lcc', resolution='c', lat_0=51.25, lon_0=-4 ) # 只绘制一次底图,后续不再重复绘制 map.drawmapboundary(fill_color='turquoise') map.fillcontinents(color='white', lake_color='aqua') map.drawcountries(linestyle='--') # 初始化当前点和轨迹线的绘图对象 x_init, y_init = map(Xpos1[0], Ypos1[0]) current_point, = map.plot(x_init, y_init, 'ro', markersize=10) trajectory_line, = map.plot([], [], 'bo-', markersize=5, alpha=0.5) def update(frame): # 更新当前点的位置 x_current, y_current = map(Xpos1[frame], Ypos1[frame]) current_point.set_data(x_current, y_current) # 更新轨迹线的内容(到当前时刻的所有点) x_trajectory, y_trajectory = map(Xpos1[:frame+1], Ypos1[:frame+1]) trajectory_line.set_data(x_trajectory, y_trajectory) # 更新标题 plt.title(f"海上漂移轨迹 - 第{frame+1}小时") return current_point, trajectory_line # 创建动画:frames是总帧数,interval是每帧间隔毫秒,blit=True只更新变化部分 ani = FuncAnimation(fig, update, frames=Duration, interval=500, blit=True) plt.show()
为什么原来的代码会叠加历史点?
matplotlib的绘图默认是叠加模式,每次调用plot()都会在当前坐标轴上添加新的绘图元素,不会自动清除之前的内容。所以需要我们手动清除轴内容(plt.cla()),或者使用动画模块只更新动态元素。
内容的提问来源于stack exchange,提问作者Jellyse
相关产品推荐
相关产品推荐

