使用Matplotlib绘制多组圆形Patches仅显示最后一组的问题求助
问题:Matplotlib绘制多组圆形仅显示最后一组
我尝试在单个Matplotlib图中绘制多组以不同中心定位的圆形集合,编写了生成圆形补丁(Patch)的函数,并将所有补丁存入total_patches列表。但将这些补丁添加到图中后,仅能看到最后一组圆形。
当前效果

期望效果

以下是我的代码:
def add_circles(center, radius_gt, area_pred, area_db): # fig, ax = plt.subplots()#figsize = (10,10)) # note we must use plt.subplots, not plt.subplot circle = plt.Circle(center, (radius_gt/2), facecolor='None', alpha=1, linewidth=1.5, linestyle='--', edgecolor='g') circle_pred = plt.Circle(center, gen_diameter(area_pred)/2, color='blue') circle_db = plt.Circle(center, gen_diameter(area_db)/2, color='r') patches = [circle_db, circle_pred, circle] return center, patches total_patches = [] center = [5,0] center, patches = add_circles(center, 3, average_3_pred, average_3_db) [total_patches.append(patch) for patch in patches] print(center) # [ax.add_patch(patch) for patch in patches] center[0] = center[0] + (5 + gen_diameter(average_3_db)/2 + gen_diameter(average_4_db)/2) center, patches = add_circles(center, 4, average_4_pred, average_4_db) [total_patches.append(patch) for patch in patches] print(center) # [ax.add_patch(patch) for patch in patches] center[0] = center[0] + (5 + gen_diameter(average_4_db)/2 + gen_diameter(average_6_db)/2) center, patches = add_circles(center, 6, average_6_pred, average_6_db) [total_patches.append(patch) for patch in patches] print(center) # [ax.add_patch(patch) for patch in patches] center[0] = center[0] + (5 + gen_diameter(average_6_db)/2 + gen_diameter(average_7_db)/2) center, patches = add_circles(center, 7, average_7_pred, average_7_db) [total_patches.append(patch) for patch in patches] print(center) # [ax.add_patch(patch) for patch in patches] center[0] = center[0] + (5 + gen_diameter(average_7_db)/2 + gen_diameter(average_9_db)/2) center, patches = add_circles(center, 9, average_9_pred, average_9_db) [total_patches.append(patch) for patch in patches] fig, ax = plt.subplots()#figsize = (10,10)) # note we must use plt.subplots, not plt.subplot [ax.add_patch(patch) for patch in total_patches] ax.set_aspect('equal') ax.set_xlim(0,80) ax.set_ylim(-10,10)
解决方案
问题出在可变对象的引用特性上:你使用的center是列表(可变类型),每次修改center[0]时,之前创建的所有plt.Circle对象里的中心参数都会被同步修改——因为plt.Circle保存的是对这个列表的引用,而非列表的副本。最终所有圆形的中心都变成了最后一次修改后的位置,所以看起来只有最后一组圆形。
修复方法有两种,核心都是让每个圆形持有独立的中心坐标:
方法1:在add_circles函数内创建中心副本
将传入的center转换为不可变的元组,或者创建列表副本,确保后续修改原center不会影响已生成的圆形:
def add_circles(center, radius_gt, area_pred, area_db): # 创建中心副本,切断与原列表的引用关联 center_copy = tuple(center) circle = plt.Circle(center_copy, (radius_gt/2), facecolor='None', alpha=1, linewidth=1.5, linestyle='--', edgecolor='g') circle_pred = plt.Circle(center_copy, gen_diameter(area_pred)/2, color='blue') circle_db = plt.Circle(center_copy, gen_diameter(area_db)/2, color='r') patches = [circle_db, circle_pred, circle] return center, patches
方法2:调用函数时传递中心副本
在每次调用add_circles前,传递center的副本而非原列表:
center = [5,0] # 传递center的副本 center, patches = add_circles(center.copy(), 3, average_3_pred, average_3_db) [total_patches.append(patch) for patch in patches] # 后续调用同样传递副本 center[0] = center[0] + (5 + gen_diameter(average_3_db)/2 + gen_diameter(average_4_db)/2) center, patches = add_circles(center.copy(), 4, average_4_pred, average_4_db) [total_patches.append(patch) for patch in patches]
两种方法都能让所有组的圆形正确显示在各自的位置上。
内容的提问来源于stack exchange,提问作者user3165683
相关产品推荐
相关产品推荐

