You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Matplotlib读取URL中PNG文件报错的原因及方案咨询

问题:Matplotlib读取URL图片报错及解决原理

问题场景

尝试用Matplotlib加载URL中的PNG图片,后续叠加聚类图层,初始代码如下:

import urllib.request as urllib2
import matplotlib.pyplot as plt

DIRECTORY = "http://commondatastorage.googleapis.com/codeskulptor-assets/"
MAP_URL = DIRECTORY + "data_clustering/USA_Counties.png"

map_file = urllib2.urlopen(MAP_URL)
map_img = plt.imread(map_file)

implot = plt.imshow(map_img)

报错信息

运行后抛出UnsupportedOperation: seek错误,完整回溯:

runfile('G:/My Drive/Python/Fundamentals of computing/AT/Application 3/untitled0.py', wdir='G:/My Drive/Python/Fundamentals of computing/AT/Application 3')
Traceback (most recent call last):

  File "G:\My Drive\Python\Fundamentals of computing\AT\Application 3\untitled0.py", line 15, in <module>
    map_img = plt.imread(map_file)

  File "C:\Users\Tomas\anaconda3\lib\site-packages\matplotlib\pyplot.py", line 2160, in imread
    return matplotlib.image.imread(fname, format)

  File "C:\Users\Tomas\anaconda3\lib\site-packages\matplotlib\image.py", line 1560, in imread
    with img_open(fname) as image:

  File "C:\Users\Tomas\anaconda3\lib\site-packages\PIL\ImageFile.py", line 116, in __init__
    self._open()

  File "C:\Users\Tomas\anaconda3\lib\site-packages\PIL\PngImagePlugin.py", line 727, in _open
    cid, pos, length = self.png.read()

  File "C:\Users\Tomas\anaconda3\lib\site-packages\PIL\PngImagePlugin.py", line 176, in read
    pos = self.fp.tell()

UnsupportedOperation: seek

环境:Anaconda3 + Spyder 5.2.2,已更新conda、Spyder及Pillow包。

可行解决方法

直接将URL传入plt.imread,跳过urllib2.urlopen步骤:

import matplotlib.pyplot as plt

DIRECTORY = "http://commondatastorage.googleapis.com/codeskulptor-assets/"
MAP_URL = DIRECTORY + "data_clustering/USA_Counties.png"

map_img = plt.imread(MAP_URL)
implot = plt.imshow(map_img)

解决原理

1. urllib2.urlopen返回对象的局限性

urllib2.urlopen()返回的是HTTPResponse对象,属于单向流式IO对象,只能按顺序读取数据,不支持seek()(移动文件指针)和tell()(获取当前指针位置)操作。而Pillow解析PNG时,需要多次移动指针读取不同块的内容(如头信息、数据块、结束块),这就触发了UnsupportedOperation错误。

2. Matplotlib对URL的内部处理逻辑

当直接传入URL给plt.imread()时,Matplotlib会自动完成以下操作:

  • 将URL对应的资源下载到一个可随机访问的临时IO对象(内存中的BytesIO或本地临时文件)
  • 该临时对象支持seek()和tell(),满足Pillow解析PNG的需求
  • 解析完成后自动清理临时资源,无需手动处理

简言之,Matplotlib封装了网络资源的读取逻辑,把流式的网络响应转换成了符合解析要求的可随机访问对象,而自行用urllib打开的响应对象不具备这个能力。

内容的提问来源于stack exchange,提问作者Tomás Monicat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 16:35:23