Is there an easy way to display a 2D array as an image using just
Tkinter? I'm aware of a TK Image canvas widget, but can't find docs
on how to use it or what an 'image' is supposed to consist of. I'm
just evaluating numerical python as a platform and this is a pretty
important functionality that is not really addressed in any of the
readily available docs.
PIL and friends seem to be more oriented to reading/writing image
formats, and are not really what I'm looking for.
Thanks,
David.
--
David Fenyes -- dfe...@home.com
see the attached message. and remember that
python.org's search facility is your friend.
> PIL and friends seem to be more oriented to reading/writing image
> formats, and are not really what I'm looking for.
since you obviously don't know what PIL can do for
you, how can you be so sure?
check out:
http://www.pythonware.com/library/pil/handbook/imagetk.htm
and the demo scripts in the source distribution.
</F>
Newsgroups: comp.lang.python
From: "Fredrik Lundh" <fre...@pythonware.com>
Subject: Re: Tkinter PhotoImage Question
Date: Fri, 12 Nov 1999 16:06:38 +0100
Ivan Van Laningham <iva...@callware.com> wrote:
> Ok, I've managed to create an image, using xx=PhotoImage(file), and I
> can retrieve pixel values from that image using xx.get(x,y).
>
> Now I want to use the put() method to write a pixel.
>
> How do I do that? I would have expected that put() would take a string
> of pixel values for the data argument, but that doesn't seem to be the
> case. ...
from the eff-bot archives:
#
# create a greyscale ramp using pure Tkinter
#
# fredrik lundh, january 1998
#
# fre...@pythonware.com
# http://www.pythonware.com
#
from Tkinter import *
# must initialize interpreter before you can create an image
root = Tk()
data = range(256) # 0..255
im = PhotoImage(width=len(data), height=1)
# tkinter wants a list of pixel lists, where each item is
# a tk colour specification (e.g. "#120432"). map the
# data to a list of strings, and convert the list to the
# appropriate tuple structure
im.put( (tuple(map(lambda v: "#%02x%02x%02x" % (v, v, v), data)),) )
# resize the image to the appropriate height
im = im.zoom(1, 32)
# and display it
w = Label(root, image=im, bd=0)
w.pack()
mainloop()
# after playing with this a little, you'll love
# the Python Imaging Library.
Hi David,
There are several ways to visualize 2-D data.
Here is how you can define the pixels for an image.
pixels = \
[ # begin list of pixel rows
#
[ # this is the first row in the image
[R11, G11, B11],
[R12, G12, B12],
...
]
#
[ # this is the second row in the image
[R21, G21, B21],
[R22, G22, B22],
...
]
...
] #end list
# Creating and managing the array of pixels may be savier, faster and easier
# with Numeric.
# The shape of the array is: (Height, Width, 3).
# This means: H rows, of W pixels, of three colours each.
image_data = Numeric.array(pixels, Numeric.UnsignedInt8).tostring()
This image_data can be used by PIL to create an image and if I recall
correctly, PIL does know how to display images on a Tkinter canvas.
---
The same image_data can be used to create an image and display it with
wxPython:
img = wxEmptyImage(width, height)
img.SetData(image_data)
myDc.DrawBitmap(img.ConvertToBitmap(), x1, y1)
---
The third and easiest way is provided by DISLIN
http://www.linmpi.mpg.de/dislin ).
It is the easiest because you do not have to create the pixel array yourself
and you can use directly Numeric arrays.
For a quick start, look for the function 'plot3'.
For more control, look into section A.24: Coloured 3-D graphics.
While plots are most easily rendered on a window created by DISLIN itself,
or in a graphics file, you can also render the plot on arbitrary windows
provided you know their handle.
---
ionel
For some reason, file attachment did not work.
Here is the content:
---
#---------------------------------------------------------------------------
#{{{ __author__
__author__ = "Ionel Simionescu"
#}}}
__doc__='''Defines various colormaps (color palettes).
Various palettes can be generated:
import lib.colormap
p = colormap.palette( name )
or
p = colormap.palette( [R,G,B] )
The returned palettes are Numeric arrays, of UnsignedInt8 typecode,
which are thus ready for translation to data usable by both PIL
and wxImage.
Converting palette indices to color pixels, that is [r,g,b] arrays
can be done in the following manner:
pixels = Numeric.take( p, indices )
'''
#---------------------------------------------------------------------------
import Numeric
#{{{ palette definitions
#---------------------------------------------------------------------------
_k = Numeric.arange(256)
#{{{ _gray
_gray = None
def _cgray():
global _gray
sk = Numeric.array([1,1,1], Numeric.Int)
_gray = Numeric.multiply.outer(_k, sk).astype(Numeric.UnsignedInt8)
return _gray
#}}}
#{{{ _cool
_cool = None
def _ccool():
global _cool
r = Numeric.array( _k )
g = Numeric.array( 255 - _k )
b = 255* Numeric.ones( ( 256, ) )
_cool =
eric.transpose(
Numeric.array([r,g,b])
).astype(Numeric.UnsignedInt8)
return _cool
#}}}
#{{{ _autumn
_autumn = None
def _cautumn():
global _autumn
_autumn = Numeric.transpose(
Numeric.array(
[255*Numeric.ones((256,)), _k, Numeric.zeros((256,))]
)
).astype(Numeric.UnsignedInt8)
return _autumn
#}}}
#{{{ _hot
_hot = None
def _chot():
global _hot
n = 86
n2 = 2*n -1
r = Numeric.choose(
Numeric.less(_
k, n),
(255, _k) # false is 0;
) # thus, its corresponding value comes first
g = Numeric.choose(
Numeric.less(_k, n2), # + Numeric.less(k, n2),
(255, _k) # false is 0;
) # 0<= k < n is 2;
# n<= k < n2 is 1
b = Numeric.choose(
Numeric.less(_k, n2),
( _k - n, 50) # false is 0;
) # k >= n2 is 1
_hot = Numeric.transpose(
Numeric.asarray([r,g,b])
).astype(Numeric.UnsignedInt8)
return _hot
#}}}
#{{{ _flag
_flag =
ric.array(
[
[0, 0, 0 ],
[255, 0, 0 ],
[255, 255, 0 ],
[0, 255, 0 ],
[0, 255, 255],
[0, 0, 255],
[255, 0, 255],
[255, 255, 255]
]*32
).astype(Numeric.UnsignedInt8)
def _cflag():
return _flag
#}}}
#{{{ _bone
_bone = None
def _cbone():
global _bone
r = _k*1.25
r = Numeric.choose(
Numeric.less(r, 255),
(255, r)
)
g = _k*0.78
g = Numeric.choose(
Numeric.less(g, 255),
(255, g)
)
b = _k*0.49
b = Numeric.choose(
Numeric.less(b, 255),
(255, b)
)
_bone = Numeric.transpose(
Numeric.asarray([r,g,b])
).astype(Numeric.UnsignedInt8)
return _bone
#}}}
#{{{ _jet
_jet = None
def _cjet():
global _jet
_x = range(64)
_xr = _x[:]
_xr.reverse()
_y = range(32, 64)
_yr = _y[:]
_yr.reverse()
_e = [255]*64
_0x = [0]*64
_0y = [0]*32
_r = _0y + _0x + _x + _e + _yr
_g = _0y + _x + _e + _xr + _0y
_b = _y + _e + _xr + _0x + _0y
_jet = [[0,0,0]]*256
for j in _k:
_jet[j] = [_r[j], _g[j], _b[j]]
_jet = Numeric.array( _jet, Numeric.UnsignedInt8 )
return _jet
#}}}
#{{{ _pink
_pink = None
def _cpink():
global _pink
_pink = Numeric.clip(
Numeric.s
qrt(
250.*( 2.*_cgray() + _chot() )/3
),
0, 255
).astype(Numeric.UnsignedInt8)
return _pink
#}}}
#{{{ _winter
_winter = None
def _cwinter():
global _winter
r = Numeric.zeros( (256,) )
g = Numeric.array( 0.5 * _k )
b = Numeric.array( 0.5 * (255-_k) )
_winter = Numeric.transpose(
Numeric.array( [r,g,b] )
).astype(Numeric.UnsignedInt8)
return _winter
#}}}
#}}}
_palette = {
'gray' : _gray,
'cool' : _cool,
'autumn': _autumn,
'hot' : _hot,
'flag' : _flag,
'bone' : _bone,
'jet' : _jet,
'pink' : _pink,
'winter': _winter,
}
_create = {
'gray' : _cgray,
'cool' : _ccool,
'autumn': _cautumn,
'hot' : _chot,
'flag' : _cflag,
'bone' : _cbone,
'jet' : _cjet,
'pink' : _cpink,
'winter': _cwinter,
}
#---------------------------------------------------------------------------
def cpalette( colour ):
'''Creates mono-colour palettes from a colour specification.'''
r,g,b = colour
m = max(r,g,b) *1.
r = _k*(r/m); g = _k*(g/m); b = _k*(b/m);
return Numeric.transpose(
Numeric.array( [r,g,b] )
).astype(Numeric.UnsignedInt8)
#---------------------------------------------------------------------------
def palette( spec ):
'''Returns a 256 colours palette.
<palette> recognizes a number of pre-defined palettes:
gray, cool, autumn, hot, flag, bone, jet, pink, winter.
Given a [R,G,B] colour specification, it will create a palette
containing shades of that colour.
'''
import types
spec_type = type(spec)
if spec_type is types.StringType:
name = spec
try: ret = _palette[name]
except KeyError: return None
if ret is None: return _create[ name ]()
return ret
if spec_type is types.ListType or spec_type is types.TupleType:
colour = spec
return cpalette( colour )
#---------------------------------------------------------------------------
#{{{ __main__
if __name__=='__main__':
print palette( 'gray' )
print palette( 'cool' )
print palette( 'autumn' )
print palette( 'hot' )
print palette( 'flag' )
print palette( 'bone' )
print palette( 'jet' )
print palette( 'pink' )
print palette( 'winter' )
print palette( [23, 56, 233] )
#}}}
For some other reason, the content was corrupted.
Here is a new try.
Sorry.
DF> Hello, Is there an easy way to display a 2D array as an image
DF> using just Tkinter? I'm aware of a TK Image canvas widget, but
DF> can't find docs on how to use it or what an 'image' is supposed
DF> to consist of. I'm just evaluating numerical python as a
DF> platform and this is a pretty important functionality that is not
DF> really addressed in any of the readily available docs.
I have written a program (part of a proprietary program suite) that
does this using PIL/Tkinter for data visualization. An additional
problem with my type of data is that it has more than 8 significant
bits. If you have similar data, you could have a look at the example
code I put on my starship webpage:
http://starship.python.net/crew/hooft/
Regards,
Rob Hooft
--
===== r...@hooft.net http://www.xs4all.nl/~hooft/rob/ =====
===== R&D, Nonius BV, Delft http://www.nonius.nl/ =====
===== PGPid 0xFA19277D ========================== Use Linux! =========