Discussion:
[Matplotlib-users] Best way to display image from URL in Python3
Ryan Nelson
2015-03-20 00:54:27 UTC
Permalink
Hello all,

I'm porting over some code that used Py2.7 urllib2.urlopen(url) to grab
some image data from the net and load with pyplot.imread. It doesn't work
quite right in Py3.4. I found a couple of refs:

https://github.com/matplotlib/matplotlib/pull/1650
http://stackoverflow.com/questions/15183170/python-crash-when-downloading-image-as-numpy-array

They suggest io.BytesIO(urllib.request.urlopen(url).read()) as a
replacement for Py3. Is this the best practice? Does anyone know a simpler
way to do this?

Ryan
Benjamin Root
2015-03-20 13:51:05 UTC
Permalink
According to the PR you reference, the fix for this was merged back in Jan
2013, so that means that this fix is in version 1.2.x and up. Are you
saying that you still can't do imread(urllib.request.urlopen(url))?
Post by Ryan Nelson
Hello all,
I'm porting over some code that used Py2.7 urllib2.urlopen(url) to grab
some image data from the net and load with pyplot.imread. It doesn't work
https://github.com/matplotlib/matplotlib/pull/1650
http://stackoverflow.com/questions/15183170/python-crash-when-downloading-image-as-numpy-array
They suggest io.BytesIO(urllib.request.urlopen(url).read()) as a
replacement for Py3. Is this the best practice? Does anyone know a simpler
way to do this?
Ryan
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website,
sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for
all
things parallel software development, from weekly thought leadership blogs
to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Ryan Nelson
2015-03-20 15:48:58 UTC
Permalink
Thanks, Ben. I should have made that more clear. If I run the code from the
PR, I get the following error:

Traceback (most recent call last):
File "junk.py", line 11, in <module>
image = pyplot.imread(data) # crash on py3.x
File
"/home/nelson/apps/miniconda/lib/python3.4/site-packages/matplotlib/pyplot.py",
line 2215, in imread
return _imread(*args, **kwargs)
File
"/home/nelson/apps/miniconda/lib/python3.4/site-packages/matplotlib/image.py",
line 1270, in imread
return handler(fname)
RuntimeError: _image_module::readpng: file not recognized as a PNG file

My code that I'm trying to port essentially does the same thing, and I get
the same error. I ran this example just now from Anaconda Python 3.4
install with MPL 1.4.3.

My impression from the PR was that this should work out of the box now. I
figured that maybe that was not quite the case. The implementations between
Py2 and 3 are quite different. Figured there must be a different way that I
wasn't aware of.

Ryan
Post by Benjamin Root
According to the PR you reference, the fix for this was merged back in Jan
2013, so that means that this fix is in version 1.2.x and up. Are you
saying that you still can't do imread(urllib.request.urlopen(url))?
Post by Ryan Nelson
Hello all,
I'm porting over some code that used Py2.7 urllib2.urlopen(url) to grab
some image data from the net and load with pyplot.imread. It doesn't work
https://github.com/matplotlib/matplotlib/pull/1650
http://stackoverflow.com/questions/15183170/python-crash-when-downloading-image-as-numpy-array
They suggest io.BytesIO(urllib.request.urlopen(url).read()) as a
replacement for Py3. Is this the best practice? Does anyone know a simpler
way to do this?
Ryan
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website,
sponsored
by Intel and developed in partnership with Slashdot Media, is your hub
for all
things parallel software development, from weekly thought leadership
blogs to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Ryan Nelson
2015-03-20 15:57:47 UTC
Permalink
For me, if I change the script from the PR to what is shown below,
everything works fine in both Python 2.7 and 3.4 (Anaconda environments,
everything updated):
##################
url = 'Loading Image...'
try:
import urllib2
data = urllib2.urlopen(url)
except Exception:
import urllib.request
from io import BytesIO
data = BytesIO(urllib.request.urlopen(url).read())

from matplotlib import pyplot

image = pyplot.imread(data) # crash on py3.x
pyplot.imshow(image)
pyplot.show()
#################
But as you can see, the Python 3 version requires the addition of BytesIO
and read(). I take it that this is not supposed to be the case.

Ryan
Post by Ryan Nelson
Thanks, Ben. I should have made that more clear. If I run the code from
File "junk.py", line 11, in <module>
image = pyplot.imread(data) # crash on py3.x
File
"/home/nelson/apps/miniconda/lib/python3.4/site-packages/matplotlib/pyplot.py",
line 2215, in imread
return _imread(*args, **kwargs)
File
"/home/nelson/apps/miniconda/lib/python3.4/site-packages/matplotlib/image.py",
line 1270, in imread
return handler(fname)
RuntimeError: _image_module::readpng: file not recognized as a PNG file
My code that I'm trying to port essentially does the same thing, and I get
the same error. I ran this example just now from Anaconda Python 3.4
install with MPL 1.4.3.
My impression from the PR was that this should work out of the box now. I
figured that maybe that was not quite the case. The implementations between
Py2 and 3 are quite different. Figured there must be a different way that I
wasn't aware of.
Ryan
Post by Benjamin Root
According to the PR you reference, the fix for this was merged back in
Jan 2013, so that means that this fix is in version 1.2.x and up. Are you
saying that you still can't do imread(urllib.request.urlopen(url))?
Post by Ryan Nelson
Hello all,
I'm porting over some code that used Py2.7 urllib2.urlopen(url) to grab
some image data from the net and load with pyplot.imread. It doesn't work
https://github.com/matplotlib/matplotlib/pull/1650
http://stackoverflow.com/questions/15183170/python-crash-when-downloading-image-as-numpy-array
They suggest io.BytesIO(urllib.request.urlopen(url).read()) as a
replacement for Py3. Is this the best practice? Does anyone know a simpler
way to do this?
Ryan
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website,
sponsored
by Intel and developed in partnership with Slashdot Media, is your hub
for all
things parallel software development, from weekly thought leadership
blogs to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Thomas Caswell
2015-03-20 16:24:51 UTC
Permalink
I think `six` (which we use to smooth over the 2/3 changes) has a way of
dealing with atleast the urllib renaming .
Post by Ryan Nelson
For me, if I change the script from the PR to what is shown below,
everything works fine in both Python 2.7 and 3.4 (Anaconda environments,
##################
url = 'http://www.libpng.org/pub/png/img_png/pngnow.png'
import urllib2
data = urllib2.urlopen(url)
import urllib.request
from io import BytesIO
data = BytesIO(urllib.request.urlopen(url).read())
from matplotlib import pyplot
image = pyplot.imread(data) # crash on py3.x
pyplot.imshow(image)
pyplot.show()
#################
But as you can see, the Python 3 version requires the addition of BytesIO
and read(). I take it that this is not supposed to be the case.
Ryan
Post by Ryan Nelson
Thanks, Ben. I should have made that more clear. If I run the code from
File "junk.py", line 11, in <module>
image = pyplot.imread(data) # crash on py3.x
File
"/home/nelson/apps/miniconda/lib/python3.4/site-packages/matplotlib/pyplot.py",
line 2215, in imread
return _imread(*args, **kwargs)
File
"/home/nelson/apps/miniconda/lib/python3.4/site-packages/matplotlib/image.py",
line 1270, in imread
return handler(fname)
RuntimeError: _image_module::readpng: file not recognized as a PNG file
My code that I'm trying to port essentially does the same thing, and I
get the same error. I ran this example just now from Anaconda Python 3.4
install with MPL 1.4.3.
My impression from the PR was that this should work out of the box now. I
figured that maybe that was not quite the case. The implementations between
Py2 and 3 are quite different. Figured there must be a different way that I
wasn't aware of.
Ryan
Post by Benjamin Root
According to the PR you reference, the fix for this was merged back in
Jan 2013, so that means that this fix is in version 1.2.x and up. Are you
saying that you still can't do imread(urllib.request.urlopen(url))?
Post by Ryan Nelson
Hello all,
I'm porting over some code that used Py2.7 urllib2.urlopen(url) to grab
some image data from the net and load with pyplot.imread. It doesn't work
https://github.com/matplotlib/matplotlib/pull/1650
http://stackoverflow.com/questions/15183170/python-crash-when-downloading-image-as-numpy-array
They suggest io.BytesIO(urllib.request.urlopen(url).read()) as a
replacement for Py3. Is this the best practice? Does anyone know a simpler
way to do this?
Ryan
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website,
sponsored
by Intel and developed in partnership with Slashdot Media, is your hub
for all
things parallel software development, from weekly thought leadership
blogs to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
------------------------------------------------------------
------------------
Dive into the World of Parallel Programming The Go Parallel Website,
sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for
all
things parallel software development, from weekly thought leadership blogs
to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Ryan Nelson
2015-03-20 16:52:49 UTC
Permalink
I can understand that switching from Py 2 to 3 is going to require a change
from urllib2.urlopen to urllib.requests.urlopen, but the addition of
BytesIO and read() makes the transition tricky. It was not obvious to me
why that wouldn't work right off the bat, which is why I had to dig up that
PR and SO post.

As an alternate question, then: would a PR be welcome that makes it so that
URL info can be passed directly to the imread function? There's already a
test to see if fname is a string. Maybe a quick check to see if it starts
with "http". Then imread could handle all of this business internally.

Thanks

Ryan
Post by Thomas Caswell
I think `six` (which we use to smooth over the 2/3 changes) has a way of
dealing with atleast the urllib renaming .
Post by Ryan Nelson
For me, if I change the script from the PR to what is shown below,
everything works fine in both Python 2.7 and 3.4 (Anaconda environments,
##################
url = 'http://www.libpng.org/pub/png/img_png/pngnow.png'
import urllib2
data = urllib2.urlopen(url)
import urllib.request
from io import BytesIO
data = BytesIO(urllib.request.urlopen(url).read())
from matplotlib import pyplot
image = pyplot.imread(data) # crash on py3.x
pyplot.imshow(image)
pyplot.show()
#################
But as you can see, the Python 3 version requires the addition of BytesIO
and read(). I take it that this is not supposed to be the case.
Ryan
Post by Ryan Nelson
Thanks, Ben. I should have made that more clear. If I run the code from
File "junk.py", line 11, in <module>
image = pyplot.imread(data) # crash on py3.x
File
"/home/nelson/apps/miniconda/lib/python3.4/site-packages/matplotlib/pyplot.py",
line 2215, in imread
return _imread(*args, **kwargs)
File
"/home/nelson/apps/miniconda/lib/python3.4/site-packages/matplotlib/image.py",
line 1270, in imread
return handler(fname)
RuntimeError: _image_module::readpng: file not recognized as a PNG file
My code that I'm trying to port essentially does the same thing, and I
get the same error. I ran this example just now from Anaconda Python 3.4
install with MPL 1.4.3.
My impression from the PR was that this should work out of the box now.
I figured that maybe that was not quite the case. The implementations
between Py2 and 3 are quite different. Figured there must be a different
way that I wasn't aware of.
Ryan
Post by Benjamin Root
According to the PR you reference, the fix for this was merged back in
Jan 2013, so that means that this fix is in version 1.2.x and up. Are you
saying that you still can't do imread(urllib.request.urlopen(url))?
Post by Ryan Nelson
Hello all,
I'm porting over some code that used Py2.7 urllib2.urlopen(url) to
grab some image data from the net and load with pyplot.imread. It doesn't
https://github.com/matplotlib/matplotlib/pull/1650
http://stackoverflow.com/questions/15183170/python-crash-when-downloading-image-as-numpy-array
They suggest io.BytesIO(urllib.request.urlopen(url).read()) as a
replacement for Py3. Is this the best practice? Does anyone know a simpler
way to do this?
Ryan
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website,
sponsored
by Intel and developed in partnership with Slashdot Media, is your hub
for all
things parallel software development, from weekly thought leadership
blogs to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
------------------------------------------------------------
------------------
Dive into the World of Parallel Programming The Go Parallel Website,
sponsored
by Intel and developed in partnership with Slashdot Media, is your hub
for all
things parallel software development, from weekly thought leadership
blogs to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Jerzy Karczmarczuk
2015-03-20 19:41:00 UTC
Permalink
Post by Ryan Nelson
For me, if I change the script from the PR to what is shown below,
everything works fine in both Python 2.7 and 3.4 (Anaconda
##################
url = 'http://www.libpng.org/pub/png/img_png/pngnow.png'
import urllib2
data = urllib2.urlopen(url)
import urllib.request
from io import BytesIO
data = BytesIO(urllib.request.urlopen(url).read())
from matplotlib import pyplot
image = pyplot.imread(data) # crash on py3.x
pyplot.imshow(image)
pyplot.show()
#################
But as you can see, the Python 3 version requires the addition of
BytesIO and read(). I take it that this is not supposed to be the case.
It works for X.png, not for X.jpg. The call of imread() fails then.
Tested also under 3.4/Anaconda.

Jerzy Karczmarczuk
Thomas Caswell
2015-03-20 20:17:11 UTC
Permalink
Despite my grumping earlier, a PR that makes URLs just work is probably a
good idea and would be merged.

Tom

On Fri, Mar 20, 2015 at 3:59 PM Jerzy Karczmarczuk <
Post by Jerzy Karczmarczuk
Post by Ryan Nelson
For me, if I change the script from the PR to what is shown below,
everything works fine in both Python 2.7 and 3.4 (Anaconda
##################
url = 'http://www.libpng.org/pub/png/img_png/pngnow.png'
import urllib2
data = urllib2.urlopen(url)
import urllib.request
from io import BytesIO
data = BytesIO(urllib.request.urlopen(url).read())
from matplotlib import pyplot
image = pyplot.imread(data) # crash on py3.x
pyplot.imshow(image)
pyplot.show()
#################
But as you can see, the Python 3 version requires the addition of
BytesIO and read(). I take it that this is not supposed to be the case.
It works for X.png, not for X.jpg. The call of imread() fails then.
Tested also under 3.4/Anaconda.
Jerzy Karczmarczuk
------------------------------------------------------------
------------------
Dive into the World of Parallel Programming The Go Parallel Website,
sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for
all
things parallel software development, from weekly thought leadership blogs
to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Ryan Nelson
2015-03-20 20:32:52 UTC
Permalink
A little update. It seems that this seems to be specific to Linux in some
way. I tried the original script from the PR under a couple of conditions:
* on Windows 7 Anaconda Python 2.7 and 3.4 -- everything works both versions
* on Anaconda Python 2.7 and 3.4 Linux version -- only the 2.7 version works
* on Gentoo Linux Python 2.7 and 3.4, MPL 1.4.3 -- only the 2.7 version
works
Hope that helps.

Ryan

On Fri, Mar 20, 2015 at 3:41 PM, Jerzy Karczmarczuk <
Post by Jerzy Karczmarczuk
Post by Ryan Nelson
For me, if I change the script from the PR to what is shown below,
everything works fine in both Python 2.7 and 3.4 (Anaconda
##################
url = 'http://www.libpng.org/pub/png/img_png/pngnow.png'
import urllib2
data = urllib2.urlopen(url)
import urllib.request
from io import BytesIO
data = BytesIO(urllib.request.urlopen(url).read())
from matplotlib import pyplot
image = pyplot.imread(data) # crash on py3.x
pyplot.imshow(image)
pyplot.show()
#################
But as you can see, the Python 3 version requires the addition of
BytesIO and read(). I take it that this is not supposed to be the case.
It works for X.png, not for X.jpg. The call of imread() fails then.
Tested also under 3.4/Anaconda.
Jerzy Karczmarczuk
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website,
sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for
all
things parallel software development, from weekly thought leadership blogs
to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Ryan Nelson
2015-03-20 20:36:24 UTC
Permalink
Thomas, sorry I missed your email.

I'll see if I can get a PR pulled together soon-ish.

Ryan
Post by Ryan Nelson
A little update. It seems that this seems to be specific to Linux in some
* on Windows 7 Anaconda Python 2.7 and 3.4 -- everything works both versions
* on Anaconda Python 2.7 and 3.4 Linux version -- only the 2.7 version works
* on Gentoo Linux Python 2.7 and 3.4, MPL 1.4.3 -- only the 2.7 version
works
Hope that helps.
Ryan
On Fri, Mar 20, 2015 at 3:41 PM, Jerzy Karczmarczuk <
Post by Jerzy Karczmarczuk
Post by Ryan Nelson
For me, if I change the script from the PR to what is shown below,
everything works fine in both Python 2.7 and 3.4 (Anaconda
##################
url = 'http://www.libpng.org/pub/png/img_png/pngnow.png'
import urllib2
data = urllib2.urlopen(url)
import urllib.request
from io import BytesIO
data = BytesIO(urllib.request.urlopen(url).read())
from matplotlib import pyplot
image = pyplot.imread(data) # crash on py3.x
pyplot.imshow(image)
pyplot.show()
#################
But as you can see, the Python 3 version requires the addition of
BytesIO and read(). I take it that this is not supposed to be the case.
It works for X.png, not for X.jpg. The call of imread() fails then.
Tested also under 3.4/Anaconda.
Jerzy Karczmarczuk
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website,
sponsored
by Intel and developed in partnership with Slashdot Media, is your hub
for all
things parallel software development, from weekly thought leadership
blogs to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Loading...