DearPyGui icon indicating copy to clipboard operation
DearPyGui copied to clipboard

Adjust plots error with set_axis_limits_auto

Open bmrv911 opened this issue 1 year ago • 1 comments

Version of Dear PyGui

Version: 2.0 Operating System: Windows 11

My Issue/Question

When you want to adjust the graphics with a checkbox using set_axis_limits, these graphics are adjusted when the checkbox is activated. Still, when the checkbox is cleared, only one axis ("x1" and "y1") returns to normal using set_axis_limits_auto, the rest of the axes do not.

To Reproduce

Steps to reproduce the behavior:

  1. Go to move the axes.
  2. Click on checkbox (activate)
  3. Move the axes (all are locked)
  4. Click on checkbox (deactivate)
  5. Move the axes (only "x1" and "y1" are unblocked)
  6. See error

Expected behavior

Activating the checkbox locks the axes, but deactivating the checkbox should unlock all axes (not only "x1" and "y1").

Screenshots/Video

https://github.com/user-attachments/assets/e5eec401-1590-411c-a73c-08bd808a5a52

Standalone, minimal, complete and verifiable example

# Python version: 3.13

import dearpygui.dearpygui as dpg

dpg.create_context()
dpg.create_viewport(title='Example', width=1024, height=768)

def call_checkbox(value):
    if value:
        x_min, x_max = 1, 4
        dpg.set_axis_limits("plot_axis_x1", x_min, x_max)
        dpg.set_axis_limits("plot_axis_x2", x_min, x_max)
        dpg.set_axis_limits("plot_axis_x3", x_min, x_max)

        y_min, y_max = -10, 10
        dpg.set_axis_limits("plot_axis_y1", y_min, y_max)
        dpg.set_axis_limits("plot_axis_y2", y_min, y_max)
        dpg.set_axis_limits("plot_axis_y3", y_min, y_max)
    else:
        try:
            dpg.set_axis_limits_auto("plot_axis_x1")
            dpg.set_axis_limits_auto("plot_axis_x2")
            dpg.set_axis_limits_auto("plot_axis_x3")
            dpg.set_axis_limits_auto("plot_axis_y1")
            dpg.set_axis_limits_auto("plot_axis_y2")
            dpg.set_axis_limits_auto("plot_axis_y3")
        except Exception as e:
            print(f"Error: {e}")

with dpg.window():
    with dpg.group():
        dpg.add_checkbox(label="Adjust graphics", callback=lambda sender, value: call_checkbox(value), default_value=False)

        with dpg.plot(label="Plots", width=800, height=600):
            dpg.add_plot_axis(dpg.mvXAxis, label="X1", tag="plot_axis_x1")
            dpg.add_plot_axis(dpg.mvYAxis, label="Y1", tag="plot_axis_y1")
            dpg.add_plot_axis(dpg.mvXAxis2, label="X2", tag="plot_axis_x2", opposite=True)
            dpg.add_plot_axis(dpg.mvYAxis2, label="Y2", tag="plot_axis_y2", opposite=True)
            dpg.add_plot_axis(dpg.mvXAxis3, label="X3", tag="plot_axis_x3", opposite=True)
            dpg.add_plot_axis(dpg.mvYAxis3, label="Y3", tag="plot_axis_y3", opposite=True)

            dpg.add_line_series([1, 2, 3, 4], [1, 4, 9, 7], label="Serie 1", parent="plot_axis_y1")
            dpg.add_line_series([1, 2, 3, 4], [1, 2, 3, 4], label="Serie 2", parent="plot_axis_y2")
            dpg.add_line_series([1, 2, 3, 4], [1, 9, 4, 5], label="Serie 3", parent="plot_axis_y3")

dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()

bmrv911 avatar Dec 03 '24 16:12 bmrv911

For reference, here are some details and analysis from the corresponding Discord thread (quoting myself)...


When you do set_axis_limits, DPG tells ImPlot to apply limits on the axis, which sets axis into the locked state. DPG repeats this every frame until you call set_axis_limits_auto. And this is where the difference starts to show up. For some reason, ImPlot does not have an API call to reset the "locked" state (axis.HasRange == true) back into "unlocked". This means, once you set an axis to a locked state via API, the only thing that can unlock it is the ImPlot engine itself. And ImPlot does indeed reset the state on every axis in BeginPlot... only that it actually happens for primary axes only (X1/Y1) - because other axes are not enabled yet at BeginPlot time (DPG configures them later, as per ImPlot API guidelines).

I'd say this is purely an ImPlot issue.

Also, in future we'd need to review the behavior of set_axis_limts, set_axis_limts_constraints, reset_axis_limts_constraints and come up with a convenient yet backwards-compatible way to deal with the limits. At the moment, set_axis_limts and set_axis_limts_constraints look a bit similar but they actually show subtle differences in behavior.

v-ein avatar Dec 05 '24 21:12 v-ein