Hello,

I just thought I'd mention a little more detail about what I've found with respect to writing grey/colorscales to vector graphics formats. The bottom line is that to plot a grayscale or colorscale in a vector graphics format without resampling, it seems at the moment that pcolorfast works best, in SVG format (not PS).

Attached is a script to try out different combinations of methods, formats, and canvas sizes. In all cases I am plotting a 10x10 numpy array. The file sizes I obtain are:

$ du -sh example*
584K    example1.ps    (imshow and 4x4 canvas)
2.2M    example2.ps    (imshow and 8x8 canvas)
 84K    example3.svg   (imshow and 4x4 canvas)
204K    example4.svg   (imshow and 8x8 canvas)
600K    example5.ps    (pcolorfast and 4x4 canvas)
2.3M    example6.ps    (pcolorfast and 8x8 canvas)
 16K    example7.svg   (pcolorfast and 4x4 canvas)
 20K    example8.svg   (pcolorfast and 8x8 canvas)

As you can see, example7.svg and example8.svg are by far the smallest files, and their sizes aren't that different, which is the way things should be as changing the canvas size shouldn't be changing much since it is a vector graphics format. It's interesting to see that imshow and pcolorfast produce different results for SVG (both smaller than the PS results)

Interestingly, pcolorfast shows no improvement compared to imshow for the PS files, and in addition, the 4x4 images are 4 times smaller than the 8x8 images, suggesting that in all cases, the colorscale has been rasterized to a finer resolution.

It might be worth seeing how the SVG driver implements this and apply the same technique to the PS driver. The fact that the SVG driver can do this suggests that the matplotlib API should be able to handle this and so all that is needed is to work on the PS driver?

As a temporary solution, it is possible to produce SVG files and convert these to PS, but this is not an ideal solution.

Let me know if you have any questions about this,

Thanks,

Thomas


 
import matplotlib
matplotlib.use('Agg')
from matplotlib.pyplot import *

import numpy as np

image = np.random.random((10,10))

fig = figure(figsize=(4,4))
ax = fig.add_subplot(111)
ax.imshow(image)
fig.savefig('example1.ps')

fig = figure(figsize=(8,8))
ax = fig.add_subplot(111)
ax.imshow(image)
fig.savefig('example2.ps')

fig = figure(figsize=(4,4))
ax = fig.add_subplot(111)
ax.imshow(image)
fig.savefig('example3.svg')

fig = figure(figsize=(8,8))
ax = fig.add_subplot(111)
ax.imshow(image)
fig.savefig('example4.svg')

fig = figure(figsize=(4,4))
ax = fig.add_subplot(111)
ax.pcolorfast(image)
fig.savefig('example5.ps')

fig = figure(figsize=(8,8))
ax = fig.add_subplot(111)
ax.pcolorfast(image)
fig.savefig('example6.ps')

fig = figure(figsize=(4,4))
ax = fig.add_subplot(111)
ax.pcolorfast(image)
fig.savefig('example7.svg')

fig = figure(figsize=(8,8))
ax = fig.add_subplot(111)
ax.pcolorfast(image)
fig.savefig('example8.svg')


On 4 Apr 2009, at 22:50, Eric Firing wrote:

Jouni, Darren,

I'm not sure who the SVG expert is, and I presume the attached message applies to pdf as well as ps. I'm bringing it to your attention because it is suggesting what would seem to be significant improvements in some backends by taking better advantage of their native image support. I know nothing about this; would either of you (or anyone else) like to comment?

Eric


I am using matplotlib to create postscript and SVG files. I am
currently using imshow to show the contents of an array, but this
means that when saving vector graphics files, matplotlib resamples the
image/array onto a finer grid. What I would like, is for code such as
this:

import matplotlib
matplotlib.use('PS')
from matplotlib.pyplot import *

import numpy as np

image = np.random.random((10,10))

fig = figure(figsize=(4,4))
ax = fig.add_subplot(111)
ax.imshow(image)
fig.savefig('example1.ps')

fig = figure(figsize=(8,8))
ax = fig.add_subplot(111)
ax.imshow(image)
fig.savefig('example2.ps')

to produce files that are the roughly the same size, rather than
different by a factor of 4. In addition, both files should be very
small since they should only contain a 10x10 bitmap in addition to the
axes+labels. Postscript and SVG (as languages) both allow a bitmap of
an arbitrary resolution to be scaled, translated, and rotated without
resampling.

I have come across the figimage method which is meant to place an
array in a plot without resampling, but I cannot figure out how to use
it like imshow, i.e. to show the image inside the axes as before. I've
also tried the pcolor functions, but it seems like they define each
pixel as an individual polygon, which is inefficient.

I was wondering if anyone had a solution to this, or if there are
plans to make matplotlib behave like this in future?

Thanks,

Thomas

------------------------------------------------------------------------------
_______________________________________________
Matplotlib-users mailing list
matplotlib-us...@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users



------------------------------------------------------------------------------
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to