Skip to content

Add demo for logarithmic histogram plotting and fix rendering (#740)#1886

Merged
VisualMelon merged 4 commits intooxyplot:developfrom
FabianNitsche:logarithmicHistogramFix
Aug 13, 2022
Merged

Add demo for logarithmic histogram plotting and fix rendering (#740)#1886
VisualMelon merged 4 commits intooxyplot:developfrom
FabianNitsche:logarithmicHistogramFix

Conversation

@FabianNitsche
Copy link
Contributor

@FabianNitsche FabianNitsche commented May 8, 2022

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:

  • Added an example for inverted rendering of histogram with logarithmic Y-axis.
  • Fixed rendering for rendering of histogram with logarithmic Y-axis.

@oxyplot/admins

@FabianNitsche
Copy link
Contributor Author

However, it seems the automatic zoom for the graph does not work. Any suggestions how to fix that?

@VisualMelon
Copy link
Contributor

VisualMelon commented May 9, 2022

I'd be very wary of this change: logs are confusing enough on bar-charts where only the height is changing when comparing bars: on a histogram, you can have different widths for bins, and a log axis renders the area completely meaningless. What is your use-case for this?

Can you describe the behaviour you are seeing and that you expect with the automatic zoom? (not able to test at the moment)

If we assume that the bins are constant width, then it could make sense to allow a base-line value as in BarSeries: it includes this value when axis is reset, which gives you a visual comparison to the base-line. If the user wants, they can set the base-line down near epsilon and specify the axes extents explicitly (using Minimum/Maximum).

But again, I don't think logs on a histogram in general make sense. Note that #740 is about bar-graphs, not histograms. It may be that a BarSeries or LinearBarSeries is more appropriate for your scenario.

@FabianNitsche
Copy link
Contributor Author

FabianNitsche commented May 9, 2022

Sorry. I should have explained more here.

It is basically about what you discussed at the end of #740 with swethakini-ofc. However, the workaround you suggested using the ColumnSeries with BaseValue = 1 is off the table since ColumnSeries has been removed from OxyPlot.

The use case is basically this:
image
(https://en.wikipedia.org/wiki/Spectrum#/media/File:Titan_atmosphere_diagram.png - Public Domain)
Or spectra that are recorded via a multi-channel-analyzer. This gives you a histogram.

I am plotting a measured spectrum that is a histogram and overlay it with a model of the spectrum. Since the height of the bins in a histogram is in y-Unit / x-Unit it corresponds to the model that is also in y-Unit / x-Unit (very common in evaluation of spectra).

And now if the baseline of the spectrum is much lower than the peaks, logarithmic plotting allows you to visualize the quality of the fit for low and high intensities of the spectrum at the same time. Additionally, it allows you to visualize regions of equal scaling, since they have the same offset in logarithmic scale (log a*x = log a + log x).

So, I want to plot LineSeries in the same plot. Does BarSeries allow this?

LinearBarSeries has the same problem when using logarithmic scale as HistogramSeries. The lower bound of the Bar is zero (and I cannot set a BaseValue) so that after transformation to logarithmic scale, the bar is plotted from positive infinity.

Both HistogramSeries and LinearBarSeries
image
become
image
when plotted in logarithmic scale.

And while the reason given at GraphPad is sensible in the example it gives, it misses the point where it does makes sense to use logarithmic scale.

And even if this is not a use case that you accept, it is still wrong how the plotting behaves when using logarithmic y-axis together with LinearBarSeries and HistogramSeries.

Do not get me wrong, I do understand why you hesitate and I can find a way around it, still using oxyplot. Thank you for your time and this great library.

@VisualMelon
Copy link
Contributor

VisualMelon commented May 9, 2022

@FabianNitsche thanks for the detail; I can't read it all right now, but I saw you said that ColumnSeries has been removed: it has been replaced with BarSeries: they were the same just flipped, you just need to set the X and Y axes explicitly to show a BarSeries vertically. Hope that helps, I'll look this over properly later!

Reading a little further, probably not if you need line series as well; linear bar series would be my first guess, but I see you've considered that already. I'll stop rushing and try to provide a proper response later.

@VisualMelon
Copy link
Contributor

VisualMelon commented May 9, 2022

You've convinced me this is worth including, and my first instinct is that the most general solution is to allow a base-line for histograms and linear bar series. It certainly makes sense for linear bar series, and for lack of better tools, I can see that the histogram could be useful; in any case, the current behaviour is terrible so we can't be making the situation any worse.

Given the weird and inconsistent behaviour at the moment, I think it would be OK to switch between 0 for linear and some default epsilon for logarithmic Y axis, the idea being that the data and the baseline (but not the epsilon if it is used (i.e. no baseline set)) determine the extent of the plot.

Rough sketch showing three scenarios: blue dotted box shows the data-extents as I've tried to describe above: for linear it is as is for BarSeries now; for log, depends on whether a baseline is set. We should update BarSeries to do this as well if it doesn't already.

image

(I think continuing the bars below the baseline would be a breaking change for BarSeries: may need a property to determine whether to crop at the baseline or not...)

(because the epislon is only used for rendering and not for guiding data-points, we have freedom to implement the rendering with them however we want, but if the epsilon method you show in this PR works across all platforms (can't think why it wouldn't, so long as the scale isn't too tight) then its fine by me)

Let me know if I've missed the point completely.

To achieve this, you'd need to change the UpdateMaxMin method so that it includes the 'top-left' and 'top-right' instead of 'bottom-left' and 'top-right' when a default epsilon is used (should include the baseline when set, and 0 when not logarithmic).

If you look at BarSeries and find all usages of baseline, that should help you find any specific bits that need to carry over if you do want to look into this.

@FabianNitsche
Copy link
Contributor Author

Thank you for looking into it. I think I get what you are envisioning.

I will look into it and update the PR as the next step for discussion.

@FabianNitsche
Copy link
Contributor Author

Just to verify, if I get it correctly, you want a BaseValue property added to HistogramSeries and LinearBarSeries as well and the double.Epsilon render trick if the y-Axis is logarithmic and BaseValue <= 0 for BarSeries, LinearBarSeries and HistogramSeries?

And also fix the UpdateMaxMin accordingly, right?

@VisualMelon
Copy link
Contributor

VisualMelon commented May 9, 2022

Yeah, I think that makes sense, but I really want to make sure it works for your use-case, because you're going to be using it and not me.

Also, don't feel you have to refit everything: if you're only interested in HistogramSeries don't worry about anything else, and don't feel you have to implement the base-lines.

I think (at least initially) the plots probably need to clamp at the base-line (as in bar-series) if set; we can worry about maybe adding a property to control that later, but with your Epsilon fix and setting the axes manually you can get pretty much achieve the alternative.

Most important (with respect to this PR) really are the changes to UpdateMaxMin will hopefully address the 'automatic zoom' issue you mentioned: basically, each series declares the data-space bounds it needs, and the axes align to this when reset. With no baseline, these bounds should be determined by the 'tops' of the bars alone.

@FabianNitsche
Copy link
Contributor Author

I am not so sure about adding BaseValue to all these series, because it becomes strange in linear y-axis scale and negative values for the BaseValue. The columns of the histogram would start at an arbitrary base value. I think we add this if we need it. But for now I would like to omit it. I continued working on the HistogramSeries please check if this goes into the right direction. I will add corresponding tests and transfer this functionality to the other series.

However, while I was debugging, I think I found a minor bug that is hindering the auto zoom. In XYAxisSeries.InternalUpdateMaxMin(List<DataPoint> points)

if (miny < this.YAxis.FilterMinValue)
{
   miny = this.YAxis.FilterMinValue;
}
this.MinY = miny;

You see, that MinY is set to FilterMinValue, which is however not a valid value of the YAxis as the documentation of FilterMinValue states. And it is correctly set to 0 for the LogarithmicAxis. However, this code actually sets MinY to an invalid value of the Axis. Although it is in the very rare case, that all y-values are invalid. Which is the case here. We would not need to change the HistogramSeries.UpdateMaxMinXY() method otherwise.

In our case, we actually do not get into the if, but still miny is initialized with the invalid value 0 at the start of the method coming from MinY.

Later XYAxisSeries.UpdateAxisMaxMin() is called and within this method YAxis.Include(this.MinY). However Include will check if the value is valid and since it is not, will not update the DataMinimum property which will stay NaN. This will eventually lead to Axis.CalculateActualMinimum() to calculate a sensible value for the minimum.

It is nothing major and your suggestion works very well. So this is probably nothing to be changed. I was just surprised to see MinY to be set to an invalid value.

@VisualMelon
Copy link
Contributor

Thanks for the clear explanations. I'm going to be very busy this week, but I'll try to remember to take a proper look at the code soon. Feel free to ping me if I don't get back to you.

@VisualMelon VisualMelon merged commit 71bc6fc into oxyplot:develop Aug 13, 2022
@VisualMelon
Copy link
Contributor

Still feels a bit odd, but merged ;) Thanks for this contribution, and sorry I took so long getting back to this.

@VisualMelon
Copy link
Contributor

Re. MinY, not sure I've understood what you are getting at: I think that's just ensuring that the data bounds are constrained to the filter minimum. As you say, a value of 0 here would make no sense, but it's OK because there will be no data down that. It could be set to an epsilon, but I think that's probably just going to obscure bugs. That said, I may be missing your point entirely.

@Dimigergo
Copy link

Hello!

I use the LinearBarSeries with LogarithmicAxis.
Do you have a plan when you implement this bug fix not only the HistoramSeries?
And do you have plan to release it soon?

I use the LinearBarSeries because my x axis is a DateTimeAxis, and I don't have any category axis and I need the DataFieldX, DataFieldY property. :(

Any workaround for the bug, until it has fixed?

Thanks for your response.

@VisualMelon
Copy link
Contributor

@Dimigergo no plans in any regard. It should be fairly easy using this PR as a reference to update BarSeries and LinearBarSeries, so I may pick that up if there is interest (thanks for registering yours).

@czegledipeter8
Copy link

Hi!

I have the same issue, please fix it as soon as possible.

Thanks in advance.

@VisualMelon
Copy link
Contributor

I need to look into revising the Histogram fix given #1925 anyway, so may look into this in the next couple of days if I have time.

@Nickythita
Copy link

Hi!
I use the LinearBarSeries too, and I have the same problem...
May I ask to fix the issue if you have some time?
Many thanks

@laszloban
Copy link

Did you have any chance on looking at the LinearBarSeries?

@VisualMelon
Copy link
Contributor

Sorry, been without a computer for about a week, and probably going to be very busy this week. Keep pestering me and hopefully I'll get around to it, since clearly this is a popular concern.

@Dimigergo
Copy link

Ping. :)

@FabianNitsche FabianNitsche deleted the logarithmicHistogramFix branch September 28, 2022 20:03
@FabianNitsche
Copy link
Contributor Author

I will have a look.

@Dimigergo
Copy link

Hello! Is there any milestone for this bug fix?
Thanks in advance! :)

@VisualMelon
Copy link
Contributor

VisualMelon commented Feb 9, 2023

@Dimigergo no; no milestone. It's high on my list of priorities, but blocking on another issue, and still requires design work so will probably be while before it's finalised.

Thanks for the ping in any case ;)

@laszloban
Copy link

Hello, I see that it is fixed for LinearBarSeries too - that is great news. Can I expect it to be released to nuget.org in the near future?

@VisualMelon
Copy link
Contributor

@Jonarw any objection to putting out a 2.1.3 in the current state? (maybe with #2066 merged)

@Jonarw
Copy link
Member

Jonarw commented Mar 26, 2024

I have certainly don't have any objections to a new release!
However, when looking at the list of unreleased changes, I think in the spirit of semantic versioning maybe this should be version 2.2? It certainly includes more than just bugfixes.
I do realize that the same may be said for version 2.1.2, but well...

@VisualMelon
Copy link
Contributor

Yes, I think you're right. Should probably add .NET 8 support explicitly as well, which reminds me I was going to take a proper look at #2061 which is very irritating problem at the moment.

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

7 participants