From 37231de1ecd13c1deb70ff19d84df5b373a6893f Mon Sep 17 00:00:00 2001 From: Andres Ortega-Guerrero <34098967+AndresOrtegaGuerrero@users.noreply.github.com> Date: Tue, 14 Jan 2025 23:01:42 +0100 Subject: [PATCH] Adding widget to control aspect ratio of plot (#1098) * Adding sliders to control the width of the plot * When plot_type has bands+pdos there is a widget to control the width of the subplots --- .../common/bands_pdos/bandpdoswidget.py | 55 +++++++++++++++++++ src/aiidalab_qe/common/bands_pdos/model.py | 19 +++++++ 2 files changed, 74 insertions(+) diff --git a/src/aiidalab_qe/common/bands_pdos/bandpdoswidget.py b/src/aiidalab_qe/common/bands_pdos/bandpdoswidget.py index 3683a44e5..61d9af4eb 100644 --- a/src/aiidalab_qe/common/bands_pdos/bandpdoswidget.py +++ b/src/aiidalab_qe/common/bands_pdos/bandpdoswidget.py @@ -235,6 +235,49 @@ def render(self): "value", ) + # Aspect ratio + self.horizontal_width_percentage = ipw.IntSlider( + min=30, + max=100, + step=5, + description="Horizonal width %:", + orientation="horizontal", + continuous_update=False, + readout=True, + readout_format=".0f", + style={"description_width": "initial"}, + layout=ipw.Layout(width="380px"), + ) + ipw.link( + (self._model, "horizontal_width_percentage"), + (self.horizontal_width_percentage, "value"), + ) + self.horizontal_width_percentage.observe( + self._on_horizontal_width_change, + "value", + ) + + self.bands_width_percentage = ipw.IntSlider( + min=10, + max=90, + step=5, + description="Bands width %:", + orientation="horizontal", + continuous_update=False, + readout=True, + readout_format=".0f", + style={"description_width": "initial"}, + layout=ipw.Layout(width="380px"), + ) + ipw.link( + (self._model, "bands_width_percentage"), + (self.bands_width_percentage, "value"), + ) + self.bands_width_percentage.observe( + self._on_bands_width_change, + "value", + ) + self.legend_interaction_description = ipw.HTML( """
@@ -289,7 +332,13 @@ def _initial_plot(self): layout=ipw.Layout(margin="0 auto"), ), self.color_selector, + self.horizontal_width_percentage, ] + if self._model.helper.plot_type == "combined": + self.children = [ + *self.children, + self.bands_width_percentage, + ] def _update_bands_projections(self, _): """Update the plot with the selected projection.""" @@ -352,3 +401,9 @@ def _trace_selector_change(self, change): def _update_trace_color(self, change): self._model.update_trace_color(change["new"]) + + def _on_horizontal_width_change(self, change): + self._model.update_horizontal_width(change["new"]) + + def _on_bands_width_change(self, change): + self._model.update_column_width_ratio(change["new"]) diff --git a/src/aiidalab_qe/common/bands_pdos/model.py b/src/aiidalab_qe/common/bands_pdos/model.py index 2439bcca2..60fa7e1cd 100644 --- a/src/aiidalab_qe/common/bands_pdos/model.py +++ b/src/aiidalab_qe/common/bands_pdos/model.py @@ -71,6 +71,12 @@ class BandsPdosModel(Model): ) image_format = tl.Unicode("png") + # Aspect ratio + horizontal_width = 850 # pixels + horizontal_width_percentage = tl.Int(100) + + bands_width_percentage = tl.Int(70) + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -290,6 +296,19 @@ def update_trace_color(self, color): # Update the color picker to match the updated trace self.color_picker = rgba_to_hex(self.plot.data[self.trace].line.color) + def update_horizontal_width(self, width_percentage): + """Update the horizontal width based on the percentge.""" + horizontal_width = int((width_percentage / 100) * self.horizontal_width) + self.plot.layout.width = horizontal_width + + def update_column_width_ratio(self, bands_width_percentage): + """Update the combined_column_widths of the combined plot based on percentage.""" + bands_width = bands_width_percentage / 100 + self.plot.update_layout( + xaxis={"domain": [0, bands_width - 0.004]}, + xaxis2={"domain": [bands_width + 0.004, 1]}, + ) + def download_image(self, _=None): """ Downloads the current plot as an image in the format specified by self.image_format.