question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Adding Annotations combined with AxisAuto derivates turn out wierd

See original GitHub issue

Hey Scott,

I really appreciate ScottPlot especially that it is so easy and simple to handle. I am trying to create a ScatterPlot with user configurable axis. In this scenario the user should be able to show a tooltip for every datapoint in the plot.

Before adding the tooltips everything looks fine:

image

But as soon as I add the tooltips and call AxisAuto the scaling between x-axis and y-axis changes and the x-axis goes full banana.

image

Hopefully you have an idea.

Cheers, Christian

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BugSearch
{
    /// <summary>
    /// A form 1.
    /// </summary>
    ///
    /// <remarks>
    /// Cfortmann, 17.02.2021.
    /// </remarks>
    public partial class Form1 : Form
    {
        /// <summary>
        /// True if is date only, false if not.
        /// </summary>
        bool isDateOnly = true;

        /// <summary>
        /// The pre xs.
        /// </summary>
        DateTime[] preXS;

        /// <summary>
        /// The ys.
        /// </summary>
        double[] ys;

        /// <summary>
        /// Default constructor.
        /// </summary>
        ///
        /// <remarks>
        /// Cfortmann, 17.02.2021.
        /// </remarks>
        public Form1()
        {
            InitializeComponent();
            this.formsPlot1.Plot.XAxis.DateTimeFormat(true);
            int Min = 0;
            int Max = 20;
            Random randNum = new Random();
            ys = Enumerable
                .Repeat(0, 100)
                .Select(i => randNum.NextDouble() * (Max - Min) + Min)
                .ToArray();
            DateTime startTime = DateTime.Parse("11.11.2020 11:12:14");        
            preXS = Enumerable
                .Repeat(0, 100)
                .Select(i => startTime.AddHours(randNum.Next(-250, 250)))
                .ToArray();
            CreatePlot(false);
        }

        /// <summary>
        /// Creates a plot.
        /// </summary>
        ///
        /// <remarks>
        /// Cfortmann, 17.02.2021.
        /// </remarks>
        ///
        /// <param name="isDateOnly">   True if is date only, false if not. </param>
        public void CreatePlot(bool isDateOnly)
        {
            double[] xs;
            if (isDateOnly)
            {
                xs = preXS.Select(x => x.Date.ToOADate()).ToArray();
            }
            else
            {
                xs = preXS.Select(x => x.ToOADate()).ToArray();
            }
            ScottPlot.Plottable.ScatterPlot plt = new ScottPlot.Plottable.ScatterPlot(xs, ys)
            {
                Label = "test",
                Color = Color.Red,
                LineStyle = 0,
            };

            this.formsPlot1.Plot.Add(plt);
            this.RedrawGraph();
        }

        /// <summary>
        /// Event handler. Called by checkedListBox1 for selected index changed events.
        /// </summary>
        ///
        /// <remarks>
        /// Cfortmann, 17.02.2021.
        /// </remarks>
        ///
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        Item check event information. </param>
        private void checkedListBox1_SelectedIndexChanged(object sender, ItemCheckEventArgs e)
        {
            switch (e.Index)
            { 
                /*
                case 0:
                    AddMinorGrid(e.NewValue == CheckState.Checked);
                    break;
                case 1:
                    ChangeTickFormat(e.NewValue == CheckState.Checked);
                    break;
                */
                case 2:
                    AddAnnotation(e.NewValue == CheckState.Checked);
                    break;
            }

            this.RedrawGraph();
        }

        /// <summary>
        /// Adds annotation.
        /// </summary>
        /// <para></para>
        /// <remarks>
        /// cfortmann, 04.12.2020.
        /// </remarks>
        public void AddAnnotation(bool isActive)
        {
            if (isActive)
            {
                foreach (var (preX, y) in Enumerable.Zip(preXS, ys))
                {
                    double x;
                    if (isDateOnly)
                    {
                        x = preX.Date.ToOADate();
                    }
                    else
                    {
                        x = preX.ToOADate();
                    }

                    ScottPlot.Plottable.Tooltip toolTip = this.formsPlot1.Plot.AddTooltip(y.ToString(), x, y);
                    toolTip.BorderWidth = 1;
                    toolTip.LabelPadding = 0;
                    toolTip.Font.Size = 10;
                    toolTip.ArrowSize = 8;
                }
            }
            else
            {
                var tooltips = this.formsPlot1.Plot.GetPlottables().OfType<ScottPlot.Plottable.Tooltip>().Select(toolTip => toolTip).ToList();
                tooltips.ForEach(toolTip => this.formsPlot1.Plot.Remove(toolTip));
            }

            this.RedrawGraph();
        }

        /// <summary>
        /// Redraw graph.
        /// </summary>
        ///
        /// <remarks>
        /// Cfortmann, 17.02.2021.
        /// </remarks>
        private void RedrawGraph()
        {
            this.formsPlot1.Plot.AxisAutoY();
            this.formsPlot1.Render();
        }

    ....
    }
}

PS: Thanks for your work and keep up with it.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
bclehmanncommented, Feb 19, 2021

I’m realizing now that converting things like the coordinates and sizes of the tooltip in coordinate space necessitates already knowing the axis limits…

I think the best solution is to have the tooltips not be considered at all in the axis calculation, which can be achieved by using double.NaN (although I think changing it so that it would accept null may be more appropriate). This does mean that auto-axising can cut off a tooltip, but this isn’t that much of an issue because tooltips automatically flow rightwards if there isn’t enough space on the left. One can consider a multi-pass AxisAuto function if this is a concern.

1reaction
ChrisAtVaultcommented, Feb 22, 2021

thank you very much 😃 This fix works like a charm 👍

Read more comments on GitHub >

github_iconTop Results From Across the Web

Chapter 18 Annotations
A vendor may – anywhere inside an annotation – add specific, possibly undocumented, annotations which are not intended to be interpreted by other...
Read more >
TikZ and pgf
It turns out that adding arrow tips is pretty easy: Karl adds the option -> to ... node placement: By adding the option...
Read more >
flexAnalysis 3.4 User Manual
To add masses from the peak list to the MS/MS list, right-click on the desired mass and choose Add Mass to MS/MS List....
Read more >
UNICORN™ 7.4 - Evaluation Manual
Auto Hide is on. Click the pin symbol to turn the function off. If Auto Hide is selected, the Result Navigator opens automatically...
Read more >
VisIt Python Interface Manual
VisIt is a distributed, parallel, visualization tool for visualizing data defined on two and three-dimensional structured and unstructured meshes.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found