Chaco: controlling the image plot sizes in a grid

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Chaco: controlling the image plot sizes in a grid

Pearu Peterson
Hi,

I am struggling with the following problem: consider a 2x2 grid of
image plots where the image sizes are

  top left: 300x300,
  top right: 100x300
  bottom left: 300x100
  bottom right: 100x100

and I would like to pack them as tightly as possible, that is, the
total size of the four plots should be 400x400.

I have tried to use GridPlotContainer as well as combinations of
H/VPlotContainers but the result is always in a 600x600 box (there is
white space around smaller image plots).

In addition, the height and width attributes of the Plot seem not to
be effective at all when using Plot.img_plot. With Plot.plot I get
expected results.

Note that this is similar to data_cube.py example where the same
problem exists: the images are placed into equal size grid boxes
leaving lots of white space around the images.

So, I wonder how to resolve this problem?

Thanks,
Pearu
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Chaco: controlling the image plot sizes in a grid

Corran Webster
Hi Pearu,

Chaco adds margins around each plot to allow room for axis labels and titles.  These aren't auto-sized by default, unfortunately, so even if you have no titles or labels, the padding will be added anyway.  The default is 50 px on all sides, so that effectively increases the total size of the plot by 100 px, which would match the 200 px increase you are seeing for a 2x2 grid.

Try setting the padding (I think that's the right trait) to 0 on each of your individual plots.

-- Corran

On Tue, Nov 16, 2010 at 5:34 AM, Pearu Peterson <[hidden email]> wrote:
Hi,

I am struggling with the following problem: consider a 2x2 grid of
image plots where the image sizes are

 top left: 300x300,
 top right: 100x300
 bottom left: 300x100
 bottom right: 100x100

and I would like to pack them as tightly as possible, that is, the
total size of the four plots should be 400x400.

I have tried to use GridPlotContainer as well as combinations of
H/VPlotContainers but the result is always in a 600x600 box (there is
white space around smaller image plots).

In addition, the height and width attributes of the Plot seem not to
be effective at all when using Plot.img_plot. With Plot.plot I get
expected results.

Note that this is similar to data_cube.py example where the same
problem exists: the images are placed into equal size grid boxes
leaving lots of white space around the images.

So, I wonder how to resolve this problem?

Thanks,
Pearu
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev


_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Chaco: controlling the image plot sizes in a grid

Peter Wang
On Tue, Nov 16, 2010 at 10:11 AM, Corran Webster <[hidden email]> wrote:
> Try setting the padding (I think that's the right trait) to 0 on each of
> your individual plots.

Yep.  Just set padding = 0 on all of the plots.  Additionally, make
sure that the "spacing" attribute of the GridPlotContainer is (0,0).
(It needs a tuple because it has both horizontal and vertical
spacing.)

-Peter
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Chaco: controlling the image plot sizes in a grid

Pearu Peterson
Hi guys,

Yes, I have played with padding and spacing.
In my statement of the problem I forgot to mention an important
condition: the images should preserve their aspect ratios.
Here follows an example that demonstrates the problem:

import numpy

from enthought.traits.api import *
from enthought.traits.ui.api import *
from enthought.chaco.api import *
from enthought.enable.api import *

class Test(HasTraits):

    a11 = numpy.ones((300,300))*110
    a12 = numpy.ones((100,300))*120
    a21 = numpy.ones((200,100))*210
    a22 = numpy.ones((100,100))*220

    plotdata = ArrayPlotData(a11=a11, a12=a12, a22=a22, a21=a21)

    p11 = Plot(plotdata, padding=1, aspect_ratio=1); p11.img_plot('a11')
    p12 = Plot(plotdata, padding=1, aspect_ratio=1/3.); p12.img_plot('a12')
    p22 = Plot(plotdata, padding=1, aspect_ratio=1); p22.img_plot('a22')
    p21 = Plot(plotdata, padding=1, aspect_ratio=3); p21.img_plot('a21')

    plot = GridContainer(shape=(2,2), spacing=(0,0))

    plot.add(p11, p12, p21, p22)

    traits_view = View(Item('plot', editor = ComponentEditor()),
                       width = 600, height = 600,
                       resizable = True
                       )

Test().configure_traits()
# eof example

Note that p22 has the same size as p11 but I want it to be 3x smaller.
Also, I want to get rid of the white space around p12 and p21 plots,
that is, the p12 should have the same width as p22 and p21 should have
the same height as p22.

Thanks,
Pearu
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Chaco: controlling the image plot sizes in a grid

Pearu Peterson
Ok, I found a solution to my problem: use default_size in Plot constructors.
Here's updated example:

import numpy

from enthought.traits.api import *
from enthought.traits.ui.api import *
from enthought.chaco.api import *
from enthought.enable.api import *

class Test(HasTraits):

    a11 = numpy.ones((300,300))*110
    a12 = numpy.ones((100,300))*120
    a21 = numpy.ones((300,100))*210
    a22 = numpy.ones((100,100))*220

    plotdata = ArrayPlotData(a11=a11, a12=a12, a22=a22, a21=a21)

    p11 = Plot(plotdata, padding=1, aspect_ratio=1,
               default_size=a11.shape); p11.img_plot('a11')
    p12 = Plot(plotdata, padding=1, aspect_ratio=1/3.,
               default_size=a12.shape); p12.img_plot('a12')
    p21 = Plot(plotdata, padding=1, aspect_ratio=3,
               default_size=a21.shape); p21.img_plot('a21')
    p22 = Plot(plotdata, padding=1, aspect_ratio=1,
               default_size=a22.shape); p22.img_plot('a22')

    plot = GridContainer(shape=(2,2), spacing=(0,0))

    plot.add(p11, p12, p21, p22)

    traits_view = View(Item('plot', editor = ComponentEditor()),
                       resizable = True
                       )
Test().configure_traits()

Best regards,
Pearu

On Tue, Nov 16, 2010 at 9:31 PM, Pearu Peterson
<[hidden email]> wrote:

> Hi guys,
>
> Yes, I have played with padding and spacing.
> In my statement of the problem I forgot to mention an important
> condition: the images should preserve their aspect ratios.
> Here follows an example that demonstrates the problem:
>
> import numpy
>
> from enthought.traits.api import *
> from enthought.traits.ui.api import *
> from enthought.chaco.api import *
> from enthought.enable.api import *
>
> class Test(HasTraits):
>
>    a11 = numpy.ones((300,300))*110
>    a12 = numpy.ones((100,300))*120
>    a21 = numpy.ones((200,100))*210
>    a22 = numpy.ones((100,100))*220
>
>    plotdata = ArrayPlotData(a11=a11, a12=a12, a22=a22, a21=a21)
>
>    p11 = Plot(plotdata, padding=1, aspect_ratio=1); p11.img_plot('a11')
>    p12 = Plot(plotdata, padding=1, aspect_ratio=1/3.); p12.img_plot('a12')
>    p22 = Plot(plotdata, padding=1, aspect_ratio=1); p22.img_plot('a22')
>    p21 = Plot(plotdata, padding=1, aspect_ratio=3); p21.img_plot('a21')
>
>    plot = GridContainer(shape=(2,2), spacing=(0,0))
>
>    plot.add(p11, p12, p21, p22)
>
>    traits_view = View(Item('plot', editor = ComponentEditor()),
>                       width = 600, height = 600,
>                       resizable = True
>                       )
>
> Test().configure_traits()
> # eof example
>
> Note that p22 has the same size as p11 but I want it to be 3x smaller.
> Also, I want to get rid of the white space around p12 and p21 plots,
> that is, the p12 should have the same width as p22 and p21 should have
> the same height as p22.
>
> Thanks,
> Pearu
>
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Chaco: controlling the image plot sizes in a grid

Robert Kern
In reply to this post by Pearu Peterson
On Tue, Nov 16, 2010 at 1:31 PM, Pearu Peterson
<[hidden email]> wrote:

> Hi guys,
>
> Yes, I have played with padding and spacing.
> In my statement of the problem I forgot to mention an important
> condition: the images should preserve their aspect ratios.
> Here follows an example that demonstrates the problem:
>
> import numpy
>
> from enthought.traits.api import *
> from enthought.traits.ui.api import *
> from enthought.chaco.api import *
> from enthought.enable.api import *
>
> class Test(HasTraits):
>
>    a11 = numpy.ones((300,300))*110
>    a12 = numpy.ones((100,300))*120
>    a21 = numpy.ones((200,100))*210
>    a22 = numpy.ones((100,100))*220
>
>    plotdata = ArrayPlotData(a11=a11, a12=a12, a22=a22, a21=a21)
>
>    p11 = Plot(plotdata, padding=1, aspect_ratio=1); p11.img_plot('a11')
>    p12 = Plot(plotdata, padding=1, aspect_ratio=1/3.); p12.img_plot('a12')
>    p22 = Plot(plotdata, padding=1, aspect_ratio=1); p22.img_plot('a22')
>    p21 = Plot(plotdata, padding=1, aspect_ratio=3); p21.img_plot('a21')
>
>    plot = GridContainer(shape=(2,2), spacing=(0,0))
>
>    plot.add(p11, p12, p21, p22)

Please note that this is not the right way to add traits to a class. See below.

To answer your question, though, you need to tell the individual plots
what sizes they ought to be. GridContainer does not know about
.aspect_ratio when doing layout. .aspect_ratio just tells Plot how to
arrange itself in the space it has been allocated.


import numpy

from enthought.traits.api import Any, HasTraits
from enthought.traits.ui.api import View, Item
from enthought.chaco.api import ArrayPlotData, Plot, GridContainer
from enthought.enable.api import ComponentEditor

class Test(HasTraits):

    plotdata = Any()
    def _plotdata_default(self):
        a11 = numpy.ones((300,300))*110
        a12 = numpy.ones((100,300))*120
        a21 = numpy.ones((200,100))*210
        a22 = numpy.ones((100,100))*220

        plotdata = ArrayPlotData(a11=a11, a12=a12, a22=a22, a21=a21)
        return plotdata

    plot = Any()
    def _plot_default(self):
        p11 = Plot(self.plotdata, padding=1, aspect_ratio=1,
fixed_preferred_size=[450, 450]); p11.img_plot('a11')
        p12 = Plot(self.plotdata, padding=1, aspect_ratio=1/3.,
fixed_preferred_size=[150, 450]); p12.img_plot('a12')
        p22 = Plot(self.plotdata, padding=1, aspect_ratio=1,
fixed_preferred_size=[150, 150]); p22.img_plot('a22')
        p21 = Plot(self.plotdata, padding=1, aspect_ratio=3,
fixed_preferred_size=[450, 150]); p21.img_plot('a21')

        plot = GridContainer(shape=(2,2), spacing=(0,0))

        plot.add(p11, p12, p21, p22)
        return plot

    traits_view = View(Item('plot', editor = ComponentEditor()),
                       width = 600, height = 600,
                       resizable = True
                       )

if __name__ == '__main__':
    Test().configure_traits()



--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
  -- Umberto Eco
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Chaco: controlling the image plot sizes in a grid

Pearu Peterson
Robert, thanks for making my example right. It's very educational.

Pearu

On Tue, Nov 16, 2010 at 9:56 PM, Robert Kern <[hidden email]> wrote:

> On Tue, Nov 16, 2010 at 1:31 PM, Pearu Peterson
> <[hidden email]> wrote:
>> Hi guys,
>>
>> Yes, I have played with padding and spacing.
>> In my statement of the problem I forgot to mention an important
>> condition: the images should preserve their aspect ratios.
>> Here follows an example that demonstrates the problem:
>>
>> import numpy
>>
>> from enthought.traits.api import *
>> from enthought.traits.ui.api import *
>> from enthought.chaco.api import *
>> from enthought.enable.api import *
>>
>> class Test(HasTraits):
>>
>>    a11 = numpy.ones((300,300))*110
>>    a12 = numpy.ones((100,300))*120
>>    a21 = numpy.ones((200,100))*210
>>    a22 = numpy.ones((100,100))*220
>>
>>    plotdata = ArrayPlotData(a11=a11, a12=a12, a22=a22, a21=a21)
>>
>>    p11 = Plot(plotdata, padding=1, aspect_ratio=1); p11.img_plot('a11')
>>    p12 = Plot(plotdata, padding=1, aspect_ratio=1/3.); p12.img_plot('a12')
>>    p22 = Plot(plotdata, padding=1, aspect_ratio=1); p22.img_plot('a22')
>>    p21 = Plot(plotdata, padding=1, aspect_ratio=3); p21.img_plot('a21')
>>
>>    plot = GridContainer(shape=(2,2), spacing=(0,0))
>>
>>    plot.add(p11, p12, p21, p22)
>
> Please note that this is not the right way to add traits to a class. See below.
>
> To answer your question, though, you need to tell the individual plots
> what sizes they ought to be. GridContainer does not know about
> .aspect_ratio when doing layout. .aspect_ratio just tells Plot how to
> arrange itself in the space it has been allocated.
>
>
> import numpy
>
> from enthought.traits.api import Any, HasTraits
> from enthought.traits.ui.api import View, Item
> from enthought.chaco.api import ArrayPlotData, Plot, GridContainer
> from enthought.enable.api import ComponentEditor
>
> class Test(HasTraits):
>
>    plotdata = Any()
>    def _plotdata_default(self):
>        a11 = numpy.ones((300,300))*110
>        a12 = numpy.ones((100,300))*120
>        a21 = numpy.ones((200,100))*210
>        a22 = numpy.ones((100,100))*220
>
>        plotdata = ArrayPlotData(a11=a11, a12=a12, a22=a22, a21=a21)
>        return plotdata
>
>    plot = Any()
>    def _plot_default(self):
>        p11 = Plot(self.plotdata, padding=1, aspect_ratio=1,
> fixed_preferred_size=[450, 450]); p11.img_plot('a11')
>        p12 = Plot(self.plotdata, padding=1, aspect_ratio=1/3.,
> fixed_preferred_size=[150, 450]); p12.img_plot('a12')
>        p22 = Plot(self.plotdata, padding=1, aspect_ratio=1,
> fixed_preferred_size=[150, 150]); p22.img_plot('a22')
>        p21 = Plot(self.plotdata, padding=1, aspect_ratio=3,
> fixed_preferred_size=[450, 150]); p21.img_plot('a21')
>
>        plot = GridContainer(shape=(2,2), spacing=(0,0))
>
>        plot.add(p11, p12, p21, p22)
>        return plot
>
>    traits_view = View(Item('plot', editor = ComponentEditor()),
>                       width = 600, height = 600,
>                       resizable = True
>                       )
>
> if __name__ == '__main__':
>    Test().configure_traits()
>
>
>
> --
> Robert Kern
>
> "I have come to believe that the whole world is an enigma, a harmless
> enigma that is made terrible by our own mad attempt to interpret it as
> though it had an underlying truth."
>   -- Umberto Eco
> _______________________________________________
> Enthought-Dev mailing list
> [hidden email]
> https://mail.enthought.com/mailman/listinfo/enthought-dev
>
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev