X Tutup
Skip to content

Fix for logarithmic axis for LinearBarSeries (#740)#1942

Merged
VisualMelon merged 7 commits intooxyplot:developfrom
FabianNitsche:logarithmicBarSeries
May 14, 2023
Merged

Fix for logarithmic axis for LinearBarSeries (#740)#1942
VisualMelon merged 7 commits intooxyplot:developfrom
FabianNitsche:logarithmicBarSeries

Conversation

@FabianNitsche
Copy link
Contributor

Fixes #740 .

Checklist

  • I have included examples or tests
  • I have updated the change log
  • I am listed in the CONTRIBUTORS file
  • I have cleaned up the commit history (use rebase and squash)

Changes proposed in this pull request:

  • As requested in PR Add demo for logarithmic histogram plotting and fix rendering (#740) #1886 I fixed the rendering for logarithmic axis in LinearBar series and added a corresponding test.
  • While fixing that, I realized, that the calculation of ActualMaximum is not correct for the logarithmic axis. Since it was not working well for the LinearBarSeries. This is fixed with this PR as well.
  • This is merely a start of discussion. Maybe you do not like what I did here.

@oxyplot/admins

@FabianNitsche
Copy link
Contributor Author

Before the fix the LineBarSeries
grafik
looked like the following when using logarithmic axis:
grafik
while the transposed loooked kind of OK:
grafik

After the fix it looks like this:
grafik
grafik

this.YAxis.Include(0.0);
if (this.YAxis.IsLogarithmic())
{
this.YAxis.Include(double.Epsilon);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this is desirable for LinearBarSeries: on a log axis, only the different between the bars matters, so we don't want to see the baseline if it's not set explicitly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That said, the behaviour isn't showing in the pictures above; I'll check this when I test everything locally.

@VisualMelon
Copy link
Contributor

VisualMelon commented Sep 29, 2022

Thanks for sorting this out. I may merge this, but we also need to solve the problem described in #1924 : epsilon is reduced to 0 on some systems. It may be that picking a different epsilon (e.g. the smallest normalised number) will work, but I've not got around to testing that, and we'd need to test it on a system which doesn't support subnormal doubles. But yeah, if it's taking a while to work out #1924, then I'll get this merged (assuming everything else is OK)

@FabianNitsche
Copy link
Contributor Author

Maybe the double.Epsilon used here could be replaced by zero, if zero itself is a valid value for the logarithmic axis. This would lead to -Infinity, but maybe that is easier to handle?

@VisualMelon
Copy link
Contributor

VisualMelon commented Sep 29, 2022

@FabianNitsche I did consider that... I can't remember why I didn't follow it up properly: I suspect it will cause issues for rendering, but it would also be easy to clamp where necessary (which would be in these sorts of series specifically). Given returning -1 makes no sense either, I'm thinking now it would probably be OK to start with that and then detect and clamp as necessary, though it's unnerving changing something so fundamental. Another option could be to compute a baseline from the clipping bounds of the axis, but this could get untidy quickly. Per my other comment, I think this is only an issue for rendering, and we don't really care where the baseline is as long as it puts us off the screen somewhere, so we don't need an epsilon for the data-ranges.

@FabianNitsche
Copy link
Contributor Author

I agree, that is a too risky change to allow zero as valid value.

So how to proceed, should I try getting rid of the double.Epsilon by including e.g. the base line in the logarithmic axis?

@VisualMelon
Copy link
Contributor

VisualMelon commented Sep 29, 2022

I'm not sure, I'm afraid (which is why it's taken me so long to not do this).

  1. The easiest way to solve this problem is probably to pass it onto the user: let them choose the baseline (per series, though having a baseline for log axes is an interesting idea itself), and set a default value of 0: log axes will still go wrong by default, but if we can throw an exception at the user it will be easy for them to set an alternative baseline and do something that makes sense for them.

  2. We could also update the rendering routines in these series to be axis aware, and just accept that we have to manually orientate everything. This sounds like more work to implement and test and maintain than just implementing a baseline feature which will be way more useful to the user.

  3. Or, we pick a new epsilon: the smallest normal double is 2.2250738585072014e-308: maybe everything 'just works' if we use that; however, it doesn't round trip through exp(log(x)). The result of that operation, 2.22507385850726E-308, does.


Right now, I think that adding a Baseline property to the series would be the best thing to do (idea 1). We'd like to do it anyway, and it side-steps this problem completely. Of course, don't feel you have to do this. If using a fuzzy epsilon (idea 3) just about works, then we could instead make the default NaN and default to 0 for linear axes and something like 1e-307 (probably wants to be a somewhat nice number, could even go with 1) for log axes.

@FabianNitsche
Copy link
Contributor Author

So to summarize. You would like to add a BaseLine property to the Series that defaults to NaN.

During rendering, If the value is NaN, then the current behavior is used for linear axis. For logarithmic axis a min value, e.g. LogarithmicAxis.MinValue (2.22507385850726E-308) is used.

If the property BaseLine is not NaN, it is respected e.g. in logarithmic plotting as the min value.

Now if this value is not valid for logarithmic plotting, an exception is thrown.

Would you like me to implement that?

@VisualMelon
Copy link
Contributor

@FabianNitsche Thank you for the clear summary: yes, if you're happy to implement that, then hopefully I'll still be happy with it once we've tested it. That said, please don't feel you have to: now that there is a plan (thanks to your efforts) I might actually get around to it myself.

@FabianNitsche
Copy link
Contributor Author

I will give it a try this weekend and will let you know. I will push to this PR, since we had also the discussion here.

@FabianNitsche
Copy link
Contributor Author

OK. Here is another suggestion. Naming is probably subpar. But I hope this will help us to get further on the topic.

@VisualMelon
Copy link
Contributor

VisualMelon commented Oct 4, 2022

Thanks for putting this together!

What I had in mind was closer to this (rough changes on top of yours): VisualMelon@62b5560 (basically uses the baseline for everything). We'd probably want to cache the ActualBaseline somewhere (the result of your method that uses the given baseline or a default). The sqrt to add some depth is a nice idea, but I think it makes more sense to not include the baseline on the log axis (e.g. like your previous iteration, check if the axis is log in UpdateAxisMaxMin and only include the value if it is set explicitly as the baseline (should always be included for linear axes).

I'm imagining now the fun bars you get on audio/signal applications showing power/attenuation/whatever as a relative dB: gains are often expressed as negative-dBs, and that implies a baseline of 1 on a log axis, or 0 on a linear axes with log values (which are easier to use than the log axis itself in many case).

@VisualMelon
Copy link
Contributor

Merging as there is lots of good stuff in here. Will commit some adjustments separately.

  • need to do something with the Histrogram Epsilon problem
  • need to review naming of BaseLine (should it be BaseValue too?)

@VisualMelon
Copy link
Contributor

VisualMelon commented May 14, 2023

Realised that BaseValue and BaseLine are completely different concepts; put some new work in #2001 building on top of this work.

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.

Colum items not rendered properly when using a logarithmic Y axis

2 participants

X Tutup