controllin the background of a plot

Hi there,

I am creating an image with mathplotlib. This image is then shown an a web page.
now ma question.
the Image is set in a large gray area. I assume it is the space needed for the axis which I do not show.
How can I suppress this gray background?

thanks
robert

here the code I use to create the image:
     def makeHlwdChart(self, values = ['a', 'd', 'e', 'f', 'b']):
         # the need for following two lines I learned by appling voodoo and pdb
         img_resource = self.context.restrictedTraverse('++resource++effizienz_balken_01.jpg')
         imp_path = img_resource.context.path
         pic = plt.imread(imp_path)
         # the picture is upside down so rotate and fip it
         pic = np.fliplr(np.rot90(pic, k=2))
         # draw it on the canvas
         plt.imshow(pic)
         frame1 = plt.gca()
         # hide axes
         frame1.axes.get_xaxis().set_visible(False)
         frame1.axes.get_yaxis().set_visible(False)
         #frame1.subplots_adjust(left=0)

         # generate the colored markers that denot the value
         # write a label so, that it is within the marker
         funs = [th, ge, hh, en, pr]
         font0 = FontProperties()
         font = font0.copy()
         font.set_weight('bold')
         for i in range(len(values)):
             # add the colord marker
             frame1.add_patch(funs[i](values[i], True))
             # get postition of the label
             p = funs[i](values[i], offset=TEXTOFFSET)
             # write the label
             frame1.text(p[0], p[1], values[i].upper(), fontproperties=font)

         return pic

When you call savefig(), you can pass it the kwarg option of bbox_inches=‘tight’ and that should help get rid of any extra area you may have.

Ben Root

···

On Saturday, July 23, 2011, robert rottermann <robert@…3680…> wrote:

Hi there,

I am creating an image with mathplotlib. This image is then shown an a web page.

now ma question.
the Image is set in a large gray area. I assume it is the space needed for the
axis which I do not show.
How can I suppress this gray background?

thanks
robert

here the code I use to create the image:
def makeHlwdChart(self, values = [‘a’, ‘d’, ‘e’, ‘f’, ‘b’]):
# the need for following two lines I learned by appling voodoo and pdb

    img_resource =

self.context.restrictedTraverse(’++resource++effizienz_balken_01.jpg’)
imp_path = img_resource.context.path
pic = plt.imread(imp_path)
# the picture is upside down so rotate and fip it

    pic = np.fliplr(np.rot90(pic, k=2))
    # draw it on the canvas
    plt.imshow(pic)
    frame1 = plt.gca()
    # hide axes
    frame1.axes.get_xaxis().set_visible(False)
    frame1.axes.get_yaxis().set_visible(False)
    #frame1.subplots_adjust(left=0)

    # generate the colored markers that denot the value
    # write a label so, that it is within the marker
    funs = [th, ge, hh, en, pr]
    font0 = FontProperties()
    font = font0.copy()
    font.set_weight('bold')
    for i in range(len(values)):
        # add the colord marker
        frame1.add_patch(funs[i](values[i], True))
        # get postition of the label
        p = funs[i](values[i], offset=TEXTOFFSET)
        # write the label
        frame1.text(p[0], p[1], values[i].upper(), fontproperties=font)
    return pic

thanks ben,
(sorry for sending answer twice)

When you call savefig(), you can pass it the kwarg option of
bbox_inches='tight' and that should help get rid of any extra area you
may have.

Ben Root

I tried to follow your advice. however it did not help. This is what I do:

- get the current figure with gcf.
- read an image from a file with imread
- save it to the canvas with imsave
- hide the axes
- call fig.savefig('out.svg', transparent=True, bbox_inches='tight', pad_inches=0)

then I create a PIL Image and return it to the calling web server.

The image is displayed with a fat (1.5 cm) gray border which I do not want.

thanks for any further intelligence

robert

here is my code cleansed of irrelevant parts

# supporting method creating the plot
def makeHlwdChart(self, values = ['a', 'd', 'e', 'f', 'b']):
     # get current axes object
     frame1 = plt.gca()
     # get current figure
     fig = plt.gcf()
     # read the image file
     pic = plt.imread(imp_path)
     # the picture is upside down so rotate and fip it
     pic = np.fliplr(np.rot90(pic, k=2))
     # draw it on the canvas
     plt.imshow(pic, figure=fig)
     # hide axes
     frame1.axes.get_xaxis().set_visible(False)
     frame1.axes.get_yaxis().set_visible(False)

     fig.savefig('out.svg', transparent=True, bbox_inches='tight', pad_inches=0)

     return pic

# method called from the web server
def __call__(self, w=300, h=300, default_format = 'PNG', set_headers=False):
     # lock graphics
     imageThreadLock.acquire()
     # we don't want different threads to write on each other's canvases,
     # make sure we have a new one
     pylab.close()
     # makeHlwdChart draws on the canvas, so we do not need its return value
     makeHlwdChart(self, values)
     canvas = pylab.get_current_fig_manager().canvas
     canvas.draw()
     imageSize = canvas.get_width_height()
     imageRgb = canvas.tostring_rgb()
     img = Image.fromstring("RGB", imageSize, imageRgb)
     #size = int(w), int(h)
     #img.thumbnail(size, Image.ANTIALIAS)
     format = img.format and img.format or default_format
     thumbnail_file = StringIO()
     ## quality parameter doesn't affect lossless formats
     img.save(thumbnail_file, format, quality=88)
     thumbnail_file.seek(0)
     if set_headers:
         self.request.RESPONSE.setHeader('Pragma', 'no-cache')
         self.request.RESPONSE.setHeader('Content-Type', 'image/%s' % format)

     # unlock graphics
     imageThreadLock.release()

     return thumbnail_file.getvalue()

thanks ben,
(sorry for sending answer twice)

When you call savefig(), you can pass it the kwarg option of
bbox_inches='tight' and that should help get rid of any extra area you
may have.

Ben Root

I tried to follow your advice. however it did not help. This is what I do:

- get the current figure with gcf.
- read an image from a file with imread
- save it to the canvas with imsave
- hide the axes
- call fig.savefig('out.svg', transparent=True, bbox_inches='tight', pad_inches=0)

then I create a PIL Image and return it to the calling web server.

The image is displayed with a fat (1.5 cm) gray border which I do not want.

thanks for any further intelligence

robert

here is my code cleansed of irrelevant parts

# supporting method creating the plot
def makeHlwdChart(self, values = ['a', 'd', 'e', 'f', 'b']):
     # get current axes object
     frame1 = plt.gca()
     # get current figure
     fig = plt.gcf()
     # read the image file
     pic = plt.imread(imp_path)
     # the picture is upside down so rotate and fip it
     pic = np.fliplr(np.rot90(pic, k=2))
     # draw it on the canvas
     plt.imshow(pic, figure=fig)
     # hide axes
     frame1.axes.get_xaxis().set_visible(False)
     frame1.axes.get_yaxis().set_visible(False)

     fig.savefig('out.svg', transparent=True, bbox_inches='tight', pad_inches=0)

     return pic

# method called from the web server
def __call__(self, w=300, h=300, default_format = 'PNG', set_headers=False):
     # lock graphics
     imageThreadLock.acquire()
     # we don't want different threads to write on each other's canvases,
     # make sure we have a new one
     pylab.close()
     # makeHlwdChart draws on the canvas, so we do not need its return value
     makeHlwdChart(self, values)
     canvas = pylab.get_current_fig_manager().canvas
     canvas.draw()
     imageSize = canvas.get_width_height()
     imageRgb = canvas.tostring_rgb()
     img = Image.fromstring("RGB", imageSize, imageRgb)
     #size = int(w), int(h)
     #img.thumbnail(size, Image.ANTIALIAS)
     format = img.format and img.format or default_format
     thumbnail_file = StringIO()
     ## quality parameter doesn't affect lossless formats
     img.save(thumbnail_file, format, quality=88)
     thumbnail_file.seek(0)
     if set_headers:
         self.request.RESPONSE.setHeader('Pragma', 'no-cache')
         self.request.RESPONSE.setHeader('Content-Type', 'image/%s' % format)

     # unlock graphics
     imageThreadLock.release()

     return thumbnail_file.getvalue()

Does the image look correct if you save it as a PNG file? It might be a problem with the SVG backend. Also, which version of matplotlib are you using. There was a lot of work on the bbox_inches stuff and this problem might have already been fixed.

Ben Root

···

On Sat, Jul 23, 2011 at 2:53 PM, robert rottermann <robert.rottermann@…3687…> wrote:

thanks ben,

(sorry for sending answer twice)

When you call savefig(), you can pass it the kwarg option of

bbox_inches=‘tight’ and that should help get rid of any extra area you

may have.

Ben Root

I tried to follow your advice. however it did not help. This is what I do:

  • get the current figure with gcf.

  • read an image from a file with imread

  • save it to the canvas with imsave

  • hide the axes

  • call fig.savefig(‘out.svg’, transparent=True, bbox_inches=‘tight’,

pad_inches=0)

then I create a PIL Image and return it to the calling web server.

The image is displayed with a fat (1.5 cm) gray border which I do not want.

thanks for any further intelligence

robert

here is my code cleansed of irrelevant parts

supporting method creating the plot

def makeHlwdChart(self, values = [‘a’, ‘d’, ‘e’, ‘f’, ‘b’]):

get current axes object

 frame1 = plt.gca()

 # get current figure

 fig = plt.gcf()

 # read the image file

pic = plt.imread(imp_path)

 # the picture is upside down so rotate and fip it

 pic = np.fliplr(np.rot90(pic, k=2))

 # draw it on the canvas

plt.imshow(pic, figure=fig)

hide axes

 frame1.axes.get_xaxis().set_visible(False)

 frame1.axes.get_yaxis().set_visible(False)

fig.savefig(‘out.svg’, transparent=True, bbox_inches=‘tight’,

pad_inches=0)

 return pic

method called from the web server

def call(self, w=300, h=300, default_format = ‘PNG’, set_headers=False):

 # lock graphics

 imageThreadLock.acquire()

 # we don't want different threads to write on each other's canvases,

 # make sure we have a new one

 pylab.close()

 # makeHlwdChart draws on the canvas, so we do not need its return value

 makeHlwdChart(self, values)

 canvas = pylab.get_current_fig_manager().canvas

 canvas.draw()

 imageSize = canvas.get_width_height()

 imageRgb = canvas.tostring_rgb()

 img = Image.fromstring("RGB", imageSize, imageRgb)

 #size = int(w), int(h)

 #img.thumbnail(size, Image.ANTIALIAS)

 format = img.format and img.format or default_format

 thumbnail_file = StringIO()

 ## quality parameter doesn't affect lossless formats

 img.save(thumbnail_file, format, quality=88)

 thumbnail_file.seek(0)

 if set_headers:

     self.request.RESPONSE.setHeader('Pragma', 'no-cache')

     self.request.RESPONSE.setHeader('Content-Type', 'image/%s' %

format)

 # unlock graphics

 imageThreadLock.release()



 return thumbnail_file.getvalue()

using png did not help,

matplotlib.__version__ : 0.99.3
numpy: 1.5.1
as provided by the newest ubuntu
thanks
robert
···

On 23/07/11 23:17, Benjamin Root wrote:

    On Sat, Jul 23, 2011 at 2:53 PM, robert > rottermann <robert.rottermann@...3687...> >         wrote:

thanks ben,

      (sorry for sending answer twice)


        > When you call savefig(), you can pass it the kwarg

option of

        > bbox_inches='tight' and that should help get rid of any

extra area you

        > may have.

        >

        > Ben Root
        I tried to follow your advice. however it did

not help. This is what I do:

        - get the current figure with gcf.

        - read an image from a file with imread

        - save it to the canvas with imsave

        - hide the axes

        - call fig.savefig('out.svg', transparent=True,

bbox_inches=‘tight’,

        pad_inches=0)



        then I create a PIL Image and return it to the calling web

server.

        The image is displayed with a fat (1.5 cm) gray border which

I do not want.

        thanks for any further intelligence



        robert



        here is my code cleansed of irrelevant parts



        # supporting method creating the plot
        def makeHlwdChart(self, values = ['a', 'd',

‘e’, ‘f’, ‘b’]):

get current axes object

            frame1 = plt.gca()

            # get current figure

            fig = plt.gcf()

            # read the image file

pic = plt.imread(imp_path)

            # the picture is upside down so rotate and fip it

            pic = np.fliplr(np.rot90(pic, k=2))

            # draw it on the canvas

plt.imshow(pic, figure=fig)

hide axes

            frame1.axes.get_xaxis().set_visible(False)

            frame1.axes.get_yaxis().set_visible(False)
          fig.savefig('out.svg',

transparent=True, bbox_inches=‘tight’,

          pad_inches=0)



              return pic



          # method called from the web server

          def __call__(self, w=300, h=300, default_format = 'PNG',

set_headers=False):

              # lock graphics

              imageThreadLock.acquire()

              # we don't want different threads to write on each

other’s canvases,

              # make sure we have a new one

              pylab.close()

              # makeHlwdChart draws on the canvas, so we do not need

its return value

              makeHlwdChart(self, values)

              canvas = pylab.get_current_fig_manager().canvas

              canvas.draw()

              imageSize = canvas.get_width_height()

              imageRgb = canvas.tostring_rgb()

              img = Image.fromstring("RGB", imageSize, imageRgb)

              #size = int(w), int(h)

              #img.thumbnail(size, Image.ANTIALIAS)

              format = img.format and img.format or default_format

              thumbnail_file = StringIO()

              ## quality parameter doesn't affect lossless formats

              img.save(thumbnail_file, format, quality=88)

              thumbnail_file.seek(0)

              if set_headers:

                  self.request.RESPONSE.setHeader('Pragma',

‘no-cache’)

                  self.request.RESPONSE.setHeader('Content-Type',

‘image/%s’ %

          format)



              # unlock graphics

              imageThreadLock.release()



              return thumbnail_file.getvalue()
      Does the image look correct if you save it as a PNG file?  It

might be a problem with the SVG backend. Also, which version
of matplotlib are you using. There was a lot of work on the
bbox_inches stuff and this problem might have already been
fixed.

      Ben Root

Ok, your version is quite old, and might be older than when the bbox_inches=‘tight’ feature was added. Unfortunately, the way savefig was designed, I think it would swallow extra kwargs.

The current matplotlib is version 1.0.1, and we are getting close to cutting a new v1.1.0 release. Debian (which Ubuntu is based on), had a policy conflict with how we packaged our documents and did not update matplotlib in their repositories (although it should be updated in time for their next release). I would recommend building from source:

http://matplotlib.sourceforge.net/users/installing.html#installing-from-source

Note that you can obtain all of the required packages for building by running:

sudo apt-get build-dep python-matplotlib

and then build matplotlib yourself from source.

I hope this helps!
Ben Root

···

On Sat, Jul 23, 2011 at 4:50 PM, robert rottermann <robert.rottermann@…3687…> wrote:

On 23/07/11 23:17, Benjamin Root wrote:

    On Sat, Jul 23, 2011 at 2:53 PM, robert > > rottermann <robert.rottermann@...3687...> > >         wrote:

thanks ben,

      (sorry for sending answer twice)


        > When you call savefig(), you can pass it the kwarg

option of

        > bbox_inches='tight' and that should help get rid of any

extra area you

        > may have.

        >

        > Ben Root
        I tried to follow your advice. however it did

not help. This is what I do:

        - get the current figure with gcf.

        - read an image from a file with imread

        - save it to the canvas with imsave

        - hide the axes

        - call fig.savefig('out.svg', transparent=True,

bbox_inches=‘tight’,

        pad_inches=0)



        then I create a PIL Image and return it to the calling web

server.

        The image is displayed with a fat (1.5 cm) gray border which

I do not want.

        thanks for any further intelligence



        robert



        here is my code cleansed of irrelevant parts



        # supporting method creating the plot
        def makeHlwdChart(self, values = ['a', 'd',

‘e’, ‘f’, ‘b’]):

get current axes object

            frame1 = plt.gca()

            # get current figure

            fig = plt.gcf()

            # read the image file

pic = plt.imread(imp_path)

            # the picture is upside down so rotate and fip it

            pic = np.fliplr(np.rot90(pic, k=2))

            # draw it on the canvas

plt.imshow(pic, figure=fig)

hide axes

            frame1.axes.get_xaxis().set_visible(False)

            frame1.axes.get_yaxis().set_visible(False)
          fig.savefig('out.svg',

transparent=True, bbox_inches=‘tight’,

          pad_inches=0)



              return pic



          # method called from the web server

          def __call__(self, w=300, h=300, default_format = 'PNG',

set_headers=False):

              # lock graphics

              imageThreadLock.acquire()

              # we don't want different threads to write on each

other’s canvases,

              # make sure we have a new one

              pylab.close()

              # makeHlwdChart draws on the canvas, so we do not need

its return value

              makeHlwdChart(self, values)

              canvas = pylab.get_current_fig_manager().canvas

              canvas.draw()

              imageSize = canvas.get_width_height()

              imageRgb = canvas.tostring_rgb()

              img = Image.fromstring("RGB", imageSize, imageRgb)

              #size = int(w), int(h)

              #img.thumbnail(size, Image.ANTIALIAS)

              format = img.format and img.format or default_format

              thumbnail_file = StringIO()

              ## quality parameter doesn't affect lossless formats

              img.save(thumbnail_file, format, quality=88)

              thumbnail_file.seek(0)

              if set_headers:

                  self.request.RESPONSE.setHeader('Pragma',

‘no-cache’)

                  self.request.RESPONSE.setHeader('Content-Type',

‘image/%s’ %

          format)



              # unlock graphics

              imageThreadLock.release()



              return thumbnail_file.getvalue()
      Does the image look correct if you save it as a PNG file?  It

might be a problem with the SVG backend. Also, which version
of matplotlib are you using. There was a lot of work on the
bbox_inches stuff and this problem might have already been
fixed.

      Ben Root

using png did not help,

matplotlib.__version__ : 0.99.3
numpy: 1.5.1
as provided by the newest ubuntu
thanks
robert

Ok, your version is quite old, and might be older than when the bbox_inches='tight' feature was added. Unfortunately, the way savefig was designed, I think it would swallow extra kwargs.

The current matplotlib is version 1.0.1, and we are getting close to cutting a new v1.1.0 release. Debian (which Ubuntu is based on), had a policy conflict with how we packaged our documents and did not update matplotlib in their repositories (although it should be updated in time for their next release). I would recommend building from source:

http://matplotlib.sourceforge.net/users/installing.html#installing-from-source

Note that you can obtain all of the required packages for building by running:

sudo apt-get build-dep python-matplotlib

and then build matplotlib yourself from source.

I hope this helps!
Ben Root

I was barking up the wrong tree..

the picture is saved with imsave correctly (without extra space around it).
However I generated it a second time using canvas.tostring_rgb() which I then send to the web server.

When I pass a StringIO instance to imsave everything works as expected.

thanks again for your help
robert