Results 1 to 7 of 7

Thread: manipulating data for log scale

  1. #1
    Join Date
    Nov 2012
    Posts
    11
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default manipulating data for log scale

    Hello,

    I have data to plot either in linear scale or in semilog scale. However, part of the dataset will be negative. It is customary in the field (semiconductor physics) to plot by taking the absolute value of the data. I have my data in array of doubles, and I pass pointers using the setRawSamples function.

    I dont want to apply fabs on my dataset, in order not to lose the negative info. Also it is necessary to easily flip from linear to log scale. So I would like to do it using the QwtLogTransform and the transform function. So I overloaded it in a derived class (see below). First this is not very flexible since the method is "const". Second I have a problem with the graph scale which goes to logMin (1E-150) whatever I do.

    I don't understand clearly what happen here (how is the scale calculated, not using transform results ?)

    Any hint welcome !


    Qt Code:
    1. class LogTransform: public QwtLogTransform
    2. {
    3. public:
    4.  
    5. virtual double transform( double value ) const override
    6. {
    7. if (value == 0) return 0;
    8. return log(fabs(value));
    9. }
    10.  
    11. virtual QwtTransform *copy() const override
    12. {
    13. return new LogTransform();
    14. }
    15.  
    16. };
    17.  
    18. and also, where the log scale is applied :
    19.  
    20. QwtLogScaleEngine* scaleEngine = new QwtLogScaleEngine();
    21. scaleEngine->setTransformation( new LogTransform() );
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,137
    Thanks
    294
    Thanked 851 Times in 838 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: manipulating data for log scale

    Second I have a problem with the graph scale which goes to logMin (1E-150) whatever I do.
    Uwe can answer about Qwt, but this problem could well be due to your comparison in line 7. A floating point value, especially one measured experimentally, is never exactly equal to zero unless it is set to exactly zero. So your comparison is probably only rarely true for your data. A better solution is to define some "epsilon" value, where if the absolute value of the number is less than epsilon, you treat it as zero. For experimental data, this is typically the minimum resolution of the intensity scale - where two measured values are treated as equal if their difference is less than the measurement error (the ability of the measurement to distinguish them).

    Qt Code:
    1. double epsilon = 1.0e-6;
    2. if ( std::abs( value ) < epsilon ) return 0;
    To copy to clipboard, switch view to plain text mode 

    First this is not very flexible since the method is "const".
    It is perfectly appropriate that these methods are defined as "const". A const method does not change the state of the class instance when it is called. In this case, transform() simply returns a new value based on the input (changing nothing), and copy() returns a new instance, again changing nothing in the class instance.

    If you need to store some value in the class instance as a member variable that changes its value when transform() or copy() are called, then declare that variable as "mutable". It is designed for that purpose - to preserve the const-ness of the interface while allowing minor side-effect changes to occur in member variables.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Nov 2012
    Posts
    11
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: manipulating data for log scale

    Hi d_stranz !

    Thanks for your helpful answer.

    My point was that an exact value of 0 is problematic, since log(0) -> minus infinity while log (1E-6) = -6. So a value close to zero, but not exactly 0 would not be a problem. So I wanted to eliminate the exact 0 value.
    I'll do a test with your suggested solution to see how the scaling behaves.
    Now for the "mutable" attribute, I learned something helpful that I did not know. I'll do some test using it as well.
    Thanks and Happy easter !

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,137
    Thanks
    294
    Thanked 851 Times in 838 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: manipulating data for log scale

    My point was that an exact value of 0 is problematic, since log(0) -> minus infinity while log (1E-6) = -6.
    I think you missed my point (and example). I did not say to convert values near zero to epsilon; I said to use the epsilon value to to determine if something was sufficiently close to zero that it could be treated as zero. You can set the actual value used for epsilon to whatever is appropriate for your instrumentation. Clipping the near zero values in this way avoids the logMin problem because you will never pass anything that small to the log() function - it will be trapped and set to zero by the epsilon comparison.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,294
    Thanked 877 Times in 825 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: manipulating data for log scale

    A logarithmic scale never goes to 0 due to its nature. And because of limitations of a double it always has a minimum - like there is a limitation for what can be displayed as a maximum.

    If you need to have a scale that includes the 0 you need to define ranges with different transformations.
    F.e logarithmic for >= 0.01 and something based on QwtPowerTransform for below.

    The "At 400" transformation in playground/scaleengine shows how to use different transformations.

    HTH,
    Uwe

  6. #6
    Join Date
    Nov 2012
    Posts
    11
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: manipulating data for log scale

    Hello
    Thanks for your answers, I think I might not have been clear in my explanations.
    Let's illustrate : I may want to draw the diode characteristic where intensity and voltage are related by : I = I0 * (exp(V/V0) - 1)
    I0 (let's say something between 10-6 and 10-9 A) and V0 are both positive constants. It is interesting to draw this curve in semi log plot because of its exponential nature. It make sense both in direct and reverse (for V both positive and négative). Of course, for V highly négative values, I will tend to -I0. So this function has negative value for negative value of V. A classical way of representing such data is to plot (semilog) absolute value of I versus V (for V both positive and négative). The point where I = 0 should for V=0 but also real data has noise, so it may happen more than once
    My point was to draw absolute value of I without modifying my raw data, but by including the absolute value in the transformation. In this way, I don't loose my original data and I don't need to make a modified copy of it.

    I will take a closer look at the already existing transformations, as suggested by Uwe. I didn't had time to experiment more up to now.

    Best regards
    Oliver

    I also need to add that for noisy data, the I value will not take dramatically low values, because of the minimal step of the measuring system. Let's say for example 1E-12, so no value of I lower than that can occur in the data.
    Last edited by oliver_mpt; 19th April 2022 at 11:37.

  7. #7
    Join Date
    Sep 2019
    Posts
    4
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: manipulating data for log scale

    Just to add, you probably want to use QwtPlotCurve::setBaseline to some reasonable number to stop your graph from starting at LOG_MIN.
    edit: this is only relevant for Sticks, forgot that. You may need to manipulate the boundingRect otherwise.
    Last edited by jhosek; 26th April 2022 at 09:27.

Similar Threads

  1. Replies: 1
    Last Post: 2nd March 2020, 17:11
  2. Auto scale, but no plot data
    By pdm in forum Qwt
    Replies: 2
    Last Post: 20th November 2015, 15:18
  3. Manipulating excel files in Qt?
    By icttrack in forum Qt Programming
    Replies: 3
    Last Post: 24th July 2010, 11:44
  4. Replies: 8
    Last Post: 25th April 2010, 21:19
  5. Replies: 1
    Last Post: 7th July 2007, 08:41

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.