hoffstadt / hoffstadt/DearPyGui

Incorrect/inconsistent fitting of axis boundaries to data in plots

Open
#1,389 0 comments 0 reactions 0 assignees View on GitHub
state: pending type: bug
Dominant language
C++
Stars
15.6k
Forks
783
PR merge metrics
No merged PRs in 30d

Description

## Version of Dear PyGui

Version: 1.0.2
Operating System: Manjaro 21.1.6 (kernel 5.10.70-1-MANJARO)
Python: 3.9.7

## My Issue/Question

Fitting the axis boundaries to the data by double-clicking on a plot does not work as expected when `equal_aspects=True` is used. For example some data points may end up outside the visible part of the plot if only double-clicking once on the plot. This issue does not affect plots with `equal_aspects=False`.

The results of using `fit_axis_data` to fit the axis boundaries to the data also differs depending on the value of `equal_aspects`. For `equal_aspects=False` one can simply call `fit_axis_data` once for each axis and the order does not matter. Multiple calls do not change the boundaries either unless e.g. the user has used the mouse to pan/move/zoom the plot. However, plots with `equal_aspects=True` may require more than two `fit_axis_data` calls to properly adjust the boundaries of both axes.

## To Reproduce

Steps to reproduce the behaviors:

### Interacting with the plots by using the mouse

1. Press "Plot data"
2. Double-click the plot on the left to show all six data points as expected
3. Double-click the plot on the right to only show four of the data points
4. Double-click the plot on the right again to show all six data points as was initially expected to happen

### Calling `fit_axis_data` (x- and then y-axis)

1. Press "Plot data"
2. Press "Fit x-axis"
3. Press "Fit y-axis"
4. The plot on the left shows all six data points as expected while the plot on the right shows only two data points
5. Press "Fit x-axis" to show four data points on the plot on the right-hand side
6. Press "Fit x-axis" to show all six data points on the plot on the right-hand side

### Calling `fit_axis_data` (y- and then x-axis)

1. Press "Plot data"
2. Press "Fit y-axis"
3. Press "Fit x-axis"
4. The plot on the left shows all six data points as expected while the plot on the right shows only four data points
5. Press "Fit x-axis" to show all six data points on the plot on the right-hand side

### Calling `fit_axis_data` (both axes)

1. Press "Plot data"
2. Press "Fit both axes"
3. The plot on the left shows all six data points as expected while the plot on the right shows only four data points
5. Press "Fit both axes" to show all six data points on the plot on the right-hand side

## Expected behavior

Double-clicking just once on a plot with `equal_aspects=True` should adjust the boundaries of both axes correctly.

More consistent behavior when calling `fit_axis_data`. Alternatively, notes in the documentation regarding the differences in behavior depending on the value of `equal_aspects` and whether or not the function calls are made in quick succession.

## Standalone, minimal, complete and verifiable example

```python
from typing import List
import dearpygui.dearpygui as dpg

x: List[float] = [
264.683349941943,
4006.81232276445,
30914.7127636813,
45201.2976814208,
65158.3875191117,
85629.8610161988,
]
y: List[float] = [
3.29849954328507,
8677.20190560254,
20206.0652066684,
17500.3528881741,
21823.9146237981,
35375.4588992787,
]
x_axis_1: int = -1
y_axis_1: int = -1
x_axis_2: int = -1
y_axis_2: int = -1

def plot_data():
dpg.add_scatter_series(x, y, parent=y_axis_1)
dpg.add_scatter_series(x, y, parent=y_axis_2)

def fit_x_axis():
dpg.fit_axis_data(x_axis_1)
dpg.fit_axis_data(x_axis_2)

def fit_y_axis():
dpg.fit_axis_data(y_axis_1)
dpg.fit_axis_data(y_axis_2)

def fit_both_axes():
fit_x_axis()
fit_y_axis()

def print_limits():
x_lim: List[float]
y_lim: List[float]
x_lim = dpg.get_axis_limits(x_axis_1)
y_lim = dpg.get_axis_limits(y_axis_1)
print(f"equal_aspects=False -> x=({x_lim[0]:.2f}, {x_lim[1]:.2f}) and y=({y_lim[0]:.2f}, {y_lim[1]:.2f})")
x_lim = dpg.get_axis_limits(x_axis_2)
y_lim = dpg.get_axis_limits(y_axis_2)
print(f"equal_aspects=True -> x=({x_lim[0]:.2f}, {x_lim[1]:.2f}) and y=({y_lim[0]:.2f}, {y_lim[1]:.2f})\n")

dpg.create_context()
dpg.create_viewport(width=800, height=416)
main_window: int
with dpg.window() as main_window:
with dpg.group(horizontal=True):
with dpg.plot(label="equal_aspects=False", width=384, height=384, equal_aspects=False):
x_axis_1 = dpg.add_plot_axis(dpg.mvXAxis, label="x")
y_axis_1 = dpg.add_plot_axis(dpg.mvYAxis, label="y")
with dpg.plot(label="equal_aspects=True", width=384, height=384, equal_aspects=True):
x_axis_2 = dpg.add_plot_axis(dpg.mvXAxis, label="x")
y_axis_2 = dpg.add_plot_axis(dpg.mvYAxis, label="y")
with dpg.group(horizontal=True):
dpg.add_button(label="Plot data", callback=plot_data)
dpg.add_button(label="Fit x-axis", callback=fit_x_axis)
dpg.add_button(label="Fit y-axis", callback=fit_y_axis)
dpg.add_button(label="Fit both axes", callback=fit_both_axes)
dpg.add_button(label="Print limits", callback=print_limits)
dpg.set_primary_window(main_window, True)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.