Highlight point near cursor with pixel space awareness
See original GitHub issueHi,
I have an issue that visually it appears that the mouse is closer to a point but is highlighting another point because of the way the calculation is made and doesn’t take into account the axis scale. Looking into the method HighlightPointNearest the formula is only looking at the actual coordinates of the points (x1 - x) * (x1 - x) + (y1 - y) * (y1 - y) and not looking how the points are drawn on the screen.
Note how visually the mouse appears closure to (2, 200) point
As I move the mouse vertically the highlighted point eventually moves from (1, 100) to (2, 200)
Is there way to factor in the pixel location or the scale of the X and Y axis when different so that the point is highlighting correctly?
Sample Project
MainWindow.xaml.cs
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
ScottPlot.PlottableScatterHighlight sphTest;
PlottableVLine vLine;
PlottableHLine hLine;
public MainWindow()
{
InitializeComponent();
double[] xs = new double[] { 1, 2 };
double[] ys = new double[] { 100, 200 };
sphTest = pltTest.plt.PlotScatterHighlight(xs, ys, lineWidth: 0, color: System.Drawing.Color.Blue, markerSize: 10);
vLine = pltTest.plt.PlotVLine(1, color: System.Drawing.Color.Red, lineStyle: LineStyle.Dash);
hLine = pltTest.plt.PlotHLine(100, color: System.Drawing.Color.Red, lineStyle: LineStyle.Dash);
pltTest.Render();
}
private void pltTest_MouseMove(object sender, MouseEventArgs e)
{
(double mouseX, double mouseY) = pltTest.GetMouseCoordinates();
sphTest.HighlightClear();
var (x, y, index) = sphTest.HighlightPointNearest(mouseX, mouseY);
int pixelX = (int)e.MouseDevice.GetPosition(pltTest).X;
int pixelY = (int)e.MouseDevice.GetPosition(pltTest).Y;
(double coordinateX, double coordinateY) = pltTest.GetMouseCoordinates();
XPixelLabel.Content = $"{pixelX:0.000}";
YPixelLabel.Content = $"{pixelY:0.000}";
XCoordinateLabel.Content = $"{coordinateX:0.00000000}";
YCoordinateLabel.Content = $"{coordinateY:0.00000000}";
vLine.position = coordinateX;
hLine.position = coordinateY;
pltTest.Render(skipIfCurrentlyRendering: true);
}
}
Issue Analytics
- State:
- Created 3 years ago
- Comments:10 (7 by maintainers)
Top Results From Across the Web
Mouse Position - ScottPlot FAQ
Highlight the Data Point Near the Cursor. Since it is easy to determine which data point is nearest the cursor, it is possible...
Read more >Cursor location and pixel value in a Jupyter notebook ...
I would like to be able to move my cursor over an image and know it's location and pixel value An example could...
Read more >How to add a highlighter to your mouse pointer in Windows ...
Near the bottom of this screen you will see a checkbox labeled Show Location of Pointer When I Press the CTRL key. Check...
Read more >How to keep track of your mouse pointer with the ...
Another tool highlights every mouse click you make. The third tool will help you move your mouse pointer long distances across the screen....
Read more >15 Animated Cursor Effects & Ideas for Your Website [+ ...
Check out some of the coolest animated cursor effects used on real websites, and learn how to create your own.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@swharden thanks for the solution… tested it on my data set works perfect.
Hi @olofszymczak, @StendProg, and @bclehmann, this is an interesting discussion! There’s a lot to unpack here, and there are multiple ways to solve this problem. I think I found an efficient working solution to the primary issue. A few different topics are addressed here, so I’ll mention them separately:
Pixel-Aware GetPointNearest()
I’m still working on the PR, but briefly I modified the code that measures distance between two points so it now optionally incorporates the ratio of scales (pixels per unit) of X and Y axes. See #722 for details.
Full code is here: ScatterPlot.cs#L324-L351
I’ll work to make this simpler, better-documented, and add a working demo. For now though, this seems to work.
Optimization may be improved
As discussed above, it may be possible to further optimize this method for speed. I haven’t benchmarked it, but if LINQ and tuples are replaced with discrete statements it may run faster. This is outside the scope of the original issue, but worth considering. I added it as a low-priority triaged task in #716 and I probably won’t do it soon, but if someone wants to do this and make a PR I’d be happy to take a look.
ScatterPlotHighlight is Deprecated in ScottPlot 4.1
This plot type was useful for a while, but it has a highly undesirable design: it mixes point distance detection with rendering. This design limits what the user can do. For example, the user could not use this plot type to render something different (like an arrow) as a highlight. Also this plot type cannot be used for Signal plots or other plot types.
In ScottPlot 4.1 a
IHasPoints
interface was created that has a fewGetPointNearest()
methods. Plottables where highlight functionality is desired can simply implement this interface. Since it does not control rendering, users can display the highlight however they want.The recommended way to display a highlighted point is to use
AddPoint()
to place a point (a scatter plot with a single X/Y value), set its marker shape to filled circle, then set its color and size how you like. When the mouse moves you can find the point nearest the mouse, then change this point’s X/Y position and visibility, and request a render. This method is demonstrated verbosely in this WinForms app: Form1.cs