Python中移除重复绘图:调用自定义draw函数出现双图问题的解决方法
解决Matplotlib调用draw()时生成两幅图的问题
我来帮你分析下问题所在,以及对应的修复方案:
问题根源
出现两幅图的核心原因通常和Matplotlib的全局绘图状态有关:
- 要么是你在调用
draw()函数之前,已经有未关闭的Matplotlib绘图窗口/Figure对象(比如之前运行过其他绘图代码没清理); - 要么是函数内的绘图逻辑不小心触发了额外的默认Figure创建(不过看你的代码,更可能是前者)。
另外,你的代码里还有个小问题:第一个嵌套循环会重复绘制所有工厂点,每次不匹配索引时都画一遍,这会导致图形冗余、线条变粗,还拖慢运行效率。
修复方案
方案1:清理现有绘图(快速解决)
在创建新Figure之前,先清除所有遗留的绘图对象,确保从头开始:
def draw(selected): open_plants=[] plt.close('all') # 清除所有已存在的Figure plt.figure(figsize=(20,12)) # 后续代码保持不变
方案2:使用面向对象API(更可靠的长期方案)
Matplotlib的面向对象写法能让你完全控制绘图容器,避免全局状态带来的意外问题。修改后的代码如下:
def draw(selected): open_plants=[] # 明确创建Figure和Axes对象 fig, ax = plt.subplots(figsize=(20,12)) # 优化:先绘制所有工厂点为黑叉(只画一次) ax.plot([p[0] for p in plants_points], [p[1] for p in plants_points], 'kx') # 收集选中的工厂点(直接通过索引获取,无需遍历整个列表) for (i,j) in selected: open_plants.append(plants_points[i]) open_plants2 = list(set(open_plants)) # 绘制选中的工厂点为蓝色方块 for (element1, element2) in open_plants2: ax.plot(element1, element2, 'bs') # 绘制客户点 ax.plot([p[0] for p in customers_points], [p[1] for p in customers_points], 'ro', label='Customers') # 绘制工厂到客户的连线 for (i,j) in selected: for k in num_list: if i == k: ax.plot( [plants_points[i][0], customers_points[j][0]], [plants_points[i][1], customers_points[j][1]], color_list[k], label=f'facility {i}' ) # 设置标签、标题和图例 ax.set_xlabel("X coordinate") ax.set_ylabel("Y coordinate") ax.set_title('Uncapacitated Facility Location Problem') ax.legend(bbox_to_anchor=(1.075, 1), title='Legend', loc='upper right') plt.tight_layout() draw({})
这个写法不仅解决了多图问题,还优化了绘图逻辑,避免了重复绘制的冗余操作。
方案3:检查前置代码
如果你在调用draw()之前运行过其他绘图代码,记得在那些代码末尾加上plt.close(),关闭对应的Figure对象,避免遗留。
内容的提问来源于stack exchange,提问作者Logan
相关产品推荐
相关产品推荐

