Bug: Image transparency varies periodically for imshow(img, aspect='auto') at high magnification

Hi!

I believe I've found a bug in matplotlib which manifests after imshow(img, aspect='auto') when only a small portion of the image is displayed, e.g: when (xmax-xmin) << img.shape[1]. The effect of the bug is that the transparency for the entire image seems to vary, seemingly as a periodic funtion of (xmax-xmin). Explicitly setting the alpha channel for each pixel has no effect.

The attached script generates a random image of a certain size, and plots it in four different subplots. The only thing that differs between the subplots are slight variations in x_max. The four subplots are labeled:

1) The background image is visible.
2) The background image is not visible!
3) The background image is faded!
4) The background image is again visible!

which reflects the actual result on my system. As the subplots are scaled (for example by resizing the window), the intensity then varies in a periodic manner in each of the subplots.

The expected result is of course that the background should be fully visible in all subplots.

Additional details:

$ python test.py --verbose-helpful
matplotlib data path /usr/lib/python2.4/site-packages/matplotlib/mpl-data
$HOME=/home/bioinfo/yohell
CONFIGDIR=/home/bioinfo/yohell/.matplotlib
loaded rc file /usr/lib/python2.4/site-packages/matplotlib/mpl-data/matplotlibrc
matplotlib version 0.87.7
verbose.level helpful
interactive is False
platform is linux2
numerix numpy 1.0
font search path ['/usr/lib/python2.4/site-packages/matplotlib/mpl-data']
loaded ttfcache file /home/bioinfo/yohell/.matplotlib/ttffont.cache
backend WXAgg version 2.6.1.2pre

In this example I used the WXAgg backend, but GTKAgg shows the same results. I've also reproduced this bug on a WinXP machine.

Thanks for an excellent plotting package!
/Joel Hedlund
Linköping University

test.py (691 Bytes)

Hi Joel,

···

On Thursday 01 February 2007 11:09:11 am Joel Hedlund wrote:

I believe I've found a bug in matplotlib which manifests after
imshow(img, aspect='auto') when only a small portion of the image is
displayed, e.g: when (xmax-xmin) << img.shape[1]. The effect of the bug
is that the transparency for the entire image seems to vary, seemingly
as a periodic funtion of (xmax-xmin). Explicitly setting the alpha
channel for each pixel has no effect.

The attached script generates a random image of a certain size, and
plots it in four different subplots. The only thing that differs between
the subplots are slight variations in x_max. The four subplots are labeled:

1) The background image is visible.
2) The background image is not visible!
3) The background image is faded!
4) The background image is again visible!

which reflects the actual result on my system. As the subplots are
scaled (for example by resizing the window), the intensity then varies
in a periodic manner in each of the subplots.

The expected result is of course that the background should be fully
visible in all subplots.

I can verify this behavior, more or less. I observe that the figure.dpi rc
setting influences the results (I tried 86.23 and 200).

Darren Dale wrote:

Hi Joel,

I believe I've found a bug in matplotlib which manifests after
imshow(img, aspect='auto') when only a small portion of the image is
displayed, e.g: when (xmax-xmin) << img.shape[1]. The effect of the bug
is that the transparency for the entire image seems to vary, seemingly
as a periodic funtion of (xmax-xmin). Explicitly setting the alpha
channel for each pixel has no effect.

The attached script generates a random image of a certain size, and
plots it in four different subplots. The only thing that differs between
the subplots are slight variations in x_max. The four subplots are labeled:

1) The background image is visible.
2) The background image is not visible!
3) The background image is faded!
4) The background image is again visible!

which reflects the actual result on my system. As the subplots are
scaled (for example by resizing the window), the intensity then varies
in a periodic manner in each of the subplots.

The expected result is of course that the background should be fully
visible in all subplots.

I can verify this behavior, more or less. I observe that the figure.dpi rc setting influences the results (I tried 86.23 and 200).

This sounds like the same bug that was noted a few months ago, in which repeated zooming to a very small part of the image ends up washing out the color entirely. I think that it was also connected with very slow rendering.

Eric

···

On Thursday 01 February 2007 11:09:11 am Joel Hedlund wrote:

I think that it was also connected with very slow rendering.

I second that. Rendering is very slow when this occurs.

A workaround is to slice the image and just plot the visible pixels, and
then to use the 'extent' keyword argument to position the slice on the
axis, e.g:

imagesc(img[a:b,ymin:ymax,:], extent=(a,b,ymin,ymax), aspect='auto')

/Joel

Hi!

I'm using matplotlib and pygtk to write a viewer for multiple sequence alignments. (Big matrices (~100x1000) of characters, usually colored by cell according to chemical properties). Now I've run into trouble since the rendering of the actual characters is very slow. I have included a small example that illustrates this. Set SHOW_LETTERS = False to see the change in rendering speed. The difference is even greater when using real data, so I would very much appreciate suggestions as to how I could improve it.

My strategy:
I create an image with the same dimension as the msa, and where each pixel is colored according to properties of the corresponding character in the msa. I plot this in the background of the figure using imshow(). At each redraw (refresh, resize, zoom...) I determine the size that each image pixel occupies at the current canvas size, and pick a font where one letter will fit inside this square. Then I put the corresponding msa letter into this square using text()/add_artist().

Would it be possible to use only one Text instance that would hold all letters, and somehow stretch that to the desired size? If so, could I expect better performance?

Does anyone have a better idea?

Thanks for an awesome plotting package!
/Joel Hedlund

msa_render_example.py (4.27 KB)