Updating the aspect_ratio of a Component causes the bounds to shrink
- Dominant language
- C
- Stars
- 97
- Forks
- 45
- PR merge metrics
- No merged PRs in 30d
Description
For the use case of drawing an image plot in Chaco with a fixed aspect ratio, setting a new aspect ratio when the image data changes can cause the bounds to shrink until the component's parent widget is resized.
The code which handles this is in `Component._enforce_aspect_ratio`, so technically this applies to all components which update their aspect ratio.
A _potential_ solution to this might be to consult the size of the `Component.window` (`AbstractWindow`) instance. However, that will only work if the component in question completely fills its window. For smaller components, we need to remember the maximum size available to be filled.
(Also, `ConstraintsContainer` might be a better option here)
Example Code
```python
import numpy as np
from chaco.api import ArrayPlotData, CMapImagePlot, Plot
from enable.api import ComponentEditor
from traits.api import (
Array, cached_property, Enum, HasTraits, Instance, Property
)
from traitsui.api import HGroup, UItem, View
IMAGE_DATA = np.random.randint(0, 256, size=(20, 10), dtype=np.uint8)
class PatchedPlot(Plot):
def draw(self, gc, **kwargs):
print(self.bounds)
# Uncomment to "fix"
# self.position = [0, 0]
# self.bounds = [gc.width(), gc.height()]
super().draw(gc, **kwargs)
class Demo(HasTraits):
plot = Instance(Plot)
data = Instance(ArrayPlotData)
img_plot = Instance(CMapImagePlot)
choice = Enum('tall', 'wide')
image_data = Property(Array, depends_on='choice')
@cached_property
def _get_image_data(self):
if self.choice == 'tall':
return IMAGE_DATA
else:
return IMAGE_DATA.T
def _data_default(self):
return ArrayPlotData(img=self.image_data)
def _plot_default(self):
plot = PatchedPlot(
self.data,
default_origin='top left',
aspect_ratio=self.image_data.shape[1] / self.image_data.shape[0]
)
self.img_plot = plot.img_plot('img')[0]
return plot
def _image_data_changed(self):
data = self.image_data
# Update the plot data source and aspect ratio
self.data.set_data('img', data)
self.plot.aspect_ratio = data.shape[1] / data.shape[0]
# Update the grid mapper
xrange = np.arange(data.shape[1])
yrange = np.arange(data.shape[0])
self.img_plot.index.set_data(xrange, yrange)
self.plot.request_redraw()
view = View(
UItem('plot', editor=ComponentEditor()),
HGroup(
UItem('choice', springy=True),
),
resizable=True,
)
if __name__ == '__main__':
Demo().configure_traits()
```
Contributor guide
Assessment
This issue has not been assessed yet.