print_figure(), savefig() and file-like objects

The 'name' attribute is only useful sometimes:
- it works for file objects (but only when the filename ends with a
format extension)
- it does not work for sys.stdout, StringIO or cStringIO file-like
objects
I think an explicit 'format' argument is better than reading a 'name'
attribute which only works sometimes.

Steve

Send instant messages to your online friends http://au.messenger.yahoo.com

···

On Fri, 2006-07-21 at 17:21 -0500, Ken McIvor wrote:

On Jul 20, 2006, at 7:53 AM, Steven Chaplin wrote:
>
> However, print_figure() does not support writing to file objects in
> different formats because it only takes a 'filename' argument and
> does not
> have an argument to allow you to specify the format.

You can usually get the filename from the "name" attribute of a file-
like object. Below is some untested pseudo-Python code that will use
the value of "format" if it's specified and will otherwise try to
pull the format from the file name. You should be able to collapse
the nested if/else structure -- I've covered all four permutations
explicitly for clarity.

I'm too swamped to put a lot of time into this code/explanation, so
please let me know if this doesn't make any sense.

Ken

def print_figure(self, fileOrString, format=None):
  extension = None

  if is_file_like(fileOrString):
    filename = getattr(fileobj, 'name', None)
  else:
    filename = fileOrString

  if filename is not None:
    # get the extension and make it all lower-case
    extension = os.path.splitext(filename, None)

  # figure out what the format is
  if extension is None:
    # no name file, so use format
    if format is None:
      raise ValueError('you must specify a format')
    else:
      pass # use the value of "format" else:
    # there's a name, but the format keyword overrides it
    if format is None:
      # use the file extension
      format = extension
    else:
      pass # use the value of "format"

  format = format.lower()
  if format not in ('png', 'ps', 'svg'):
    raise ValueError('invalid file format %r' % (format,))

  # At this point in the method, "format" is the requested file format.

Steve,

I am aware of the caveats associated with the "name" attribute, which is why the code I sent you attempts to do the right thing when it doesn't exist. I hadn't considered the case of stdout, but you could probably detect situations like that by testing to see if the extension is the empty string:

  # figure out what the format is
  if extension is None or extension == '':
    ...

However, this variety of special case handling could make things more confusing for beginning users. I think ultimately you should do whatever you think strikes the best balance between convenience and clarity.

···

On Jul 21, 2006, at 7:27 PM, Steven Chaplin wrote:

I think an explicit 'format' argument is better than reading a 'name'
attribute which only works sometimes.

In general I tend to agree with you, but I'd like to see Just Work when writing to an open file. I don't have a lot of stake in this either way, since I spend most of my time with matplotlib pushing the RGB data onto wxPython widgets.

Ken