Skip to content

Fix get_plot_mouse_pos() precision by calculating on-demand#2596

Open
Entrpi wants to merge 20 commits intohoffstadt:masterfrom
Entrpi:master
Open

Fix get_plot_mouse_pos() precision by calculating on-demand#2596
Entrpi wants to merge 20 commits intohoffstadt:masterfrom
Entrpi:master

Conversation

@Entrpi
Copy link

@Entrpi Entrpi commented Jan 12, 2026

Description:

Fixes #1847 - get_plot_mouse_pos() returns imprecise/stale values when using time-scale axes with Unix timestamps.

The existing implementation caches mouse position as float during rendering, only updating when ImPlot::IsPlotHovered() returns true. This causes two problems:

  1. Precision loss: float cannot represent Unix timestamps with sub-second precision
  2. Stale values: The cached value doesn't update reliably, causing the position to appear "frozen"

This fix:

  • Stores plot geometry (position, size, axis limits as double) during render instead of mouse position
  • Adds optional plot parameter to get_plot_mouse_pos(plot=tag)
  • When plot is specified, calculates position on-demand using current mouse coords + cached geometry
  • Returns double precision values via FloatList instead of IntList
  • Maintains full backward compatibility: no plot arg = legacy cached behavior

API change:

# New (accurate, on-demand calculation):
dpg.get_plot_mouse_pos(plot="my_plot")

# Old (still works, legacy cached value):
dpg.get_plot_mouse_pos()

Real-world use case:

This fix was developed for MPM-1010B Power Monitor, a real-time AC power monitoring tool with multi-timescale visualization. The app displays hover tooltips showing exact readings at the cursor position. Before this fix, tooltips would only update at ~7 discrete "slices" across the plot width due to float precision loss with Unix timestamps.

Concerning Areas:

  • The geometry cache adds 48 bytes per plot (6 doubles)
  • Calculation happens on every call when plot is specified (simple linear interpolation, negligible cost)
  • Tested on macOS with Python 3.14

The existing implementation cached mouse position only when
ImPlot::IsPlotHovered() returned true during rendering, causing
the position to become stale/frozen even while hovering.

This fix:
- Stores plot geometry (position, size, axis limits) during render
- Calculates mouse position on-demand when get_plot_mouse_pos(plot=tag)
  is called, using current mouse position + cached geometry
- Maintains backward compatibility: no plot arg = legacy cached value

API change:
  get_plot_mouse_pos(plot=None)
  - plot: Optional plot tag/UUID for on-demand calculation
  - Returns: (x, y) tuple in plot coordinates
Exposes ImGui's DragIntRange2/DragFloatRange2 as new DearPyGui widgets:
- add_drag_int_range(): Two linked int drag boxes with min <= max constraint
- add_drag_float_range(): Two linked float drag boxes with min <= max constraint

Both widgets support:
- Separate format strings for min/max values
- Speed, min_value, max_value bounds
- clamped and no_input flags
- All standard widget options (callback, drag/drop, etc.)

Note: These are linked drag boxes, not visual range sliders with
a colored bar. A visual range slider would require custom widget
implementation.
Custom range slider widgets that show a colored bar with two draggable
handles for selecting a value range. Features:
- Visual slider with filled region between min and max handles
- Separate format strings for min and max values
- Optional step parameter for value snapping (snap to intervals)
- Integer and float variants
- Proper clamping and constraint enforcement (min <= max)

New ImGui functions:
- SliderFloatRange2(label, v_min, v_max, ...)
- SliderIntRange2(label, v_min, v_max, ...)

New DearPyGui functions:
- add_slider_float_range()
- add_slider_int_range()
@Entrpi Entrpi requested a review from hoffstadt as a code owner January 12, 2026 07:37
@v-ein
Copy link
Collaborator

v-ein commented Jan 12, 2026

This PR seems to also update Dear ImGui - is that correct? Unfortunately that's a no-go because we want to single out such large changes as separate PRs (see for example #2275, it was a lot of work to get everything in order).

FWIW, I'm currently working on an update of ImGui, ImPlot, and ImNodes (honestly, the latter two almost didn't change). This will be a separate PR and most probably a separate release.

Here's the plan:

  • We already have a number of PRs merged into master since the last release, some of them quite large, which warrants a new release.
  • We'll merge several more PRs that I need before going forward with my ImGui update.
  • Once these are ready, we'll cut a release, probably version 2.2.
  • Shortly after that, I'll make another PR that updates ImGui. Once this one is sufficiently tested, we'll cut yet another release, 2.3. This will hopefully be a very short release cycle, and the only reason for doing it like that is to make sure nothing "breaks too much" - and if it does, people out there have a version to roll back to.
  • After 2.3, other PRs will be considered, including yours and some other quite deep-going things.

Change io.Fonts->TexWidth/TexHeight to io.Fonts->TexData->Width/Height
to match imgui 1.92+ API changes.
imnodes:
- ImDrawCmd::TextureId -> TexRef
- ImDrawList::_TextureIdStack -> _TextureStack

implot:
- ImFont::FontSize -> LegacySize
- ImFont::FindGlyph -> ImFontBaked::FindGlyph
- ImGuiWindow::CalcFontSize() -> FontRefSize
- ImFontAtlas::TexID -> TexRef.GetTexID()

Also update implot submodule to Entrpi fork with fixes.
macOS x64 (Intel) builds were unreliable on GitHub Actions.
Apple Silicon (arm64) builds are sufficient for modern macOS users.
@Entrpi
Copy link
Author

Entrpi commented Jan 13, 2026

Thanks for the context on the release plan!

In case it's helpful for your upcoming ImGui update work, I've been working on porting DearPyGui to current imgui master (merged into docking). The main API changes I encountered:

ImGui 1.92+ breaking changes:

  • ImGuiChildFlags_BorderImGuiChildFlags_Borders
  • ImGuiWindowFlags_NavFlattenedImGuiChildFlags_NavFlattened
  • ImFont::FontSizeLegacySize, glyph access via GetFontBaked()
  • ImFontAtlas::TexID/TexWidth/TexHeightTexRef.GetTexID(), TexData->Width/Height
  • ImDrawCmd::TextureIdTexRef, ImDrawList::_TextureIdStack_TextureStack
  • ImGuiWindow::CalcFontSize()FontRefSize
  • SetCurrentFont(font)SetCurrentFont(font, size, size)
  • Metal backend: ImGui_ImplMetal_CreateFontsTexture/DestroyFontsTexture removed (now automatic)

Forks with working builds:

Wheels building successfully for Python 3.10-3.14 on Windows x64, Linux x64/arm64, macOS arm64. Tested the new SliderRange2/DragRange2 functionality in DearPyGui with all the current edits - working as expected (drag handles, Cmd/Ctrl+Click text input, step snapping, etc.).

Also worth noting: the SliderFloatRange2/SliderIntRange2 widgets are being reviewed upstream at ocornut/imgui#9164 - Omar is actively refining the API. If it gets merged before your ImGui update, you'd get the widgets included automatically.

Happy to split out just the DearPyGui bindings for SliderRange2/DragRange2 into a separate PR once you're ready for it after 2.3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Insufficient precision of the get_plot_mouse_pos()

2 participants