Log Scale

2009-08-22
2014-10-02
  • Rémy Claverie

    Rémy Claverie - 2009-08-22

    Hi everybody,

    It could be nice to change the linear scale of the axes for non linear as Logarithmic.
    Is it difficult ti implement ?

    Thanks a lot

    Rémy

     
  • JuPe

    JuPe - 2009-09-19

    Hi!

    I've implemented couple of wxMathPlot layers (bar chart and point layer), and I think I will do logarithm scale too . Also I'm developing some kind of gpPanel which use wxMathPlot library. Maybe someday in this year, when it's almost ready, I publish it.. :)

    -JuPe

     
  • Byron

    Byron - 2014-10-02

    For those who are interested in logarithmic scales, maybe this function will get you started:

    typedef enum
    {
    mpLOG_TYPE_1_2_5,
    mpLOG_TYPE_1_3_10,
    mpLOG_TYPE_10n,
    mpLOG_TYPE_2DIGITS
    } scaleType;
    typedef struct
    {
    double min, max, min_exp, max_exp, delta, vals [10];
    wxString label [10];
    size_t num_labels;
    scaleType type;
    } scaleStruct_t;
    // Configure a logarithm scale labels. NUM_TICKS labels will be assigned to
    // the scale if scale.type == mpLOG_TYPES_2DIGITS; otherwise, the scale will
    // have [1, 2, 5, 10, 20, ...], [1, 3, 10, 30, 100, ...], or even powers of
    // ten (whichever fits the data best). For '2DIGITS' type the scale will be
    // divided evenly and the labels' mantissae will keep two significant digits.
    // If scale.type is assigned a different type prior to configuring the scale,
    // the function will choose which of the remaining three types fit the data
    // best and return this type in scale.type.
    // Before calling this function, the program must search the data for the
    // maximum value and the minimum value to be plotted and it must assign these
    // to scale.max and scale.min, respectively.
    // config_log_scale will assign the remaining scaleStruct_t entries:
    // scale.min and scale.max will be unchanged
    // scale.type will contain the type of interval chosen
    // scale.num_labels will contain the number of labels needed to fill
    // the entire length of the scale
    // scale.vals will contain all of the chosen label values
    // scale.labels will contain the text needed to draw the labels
    #define NUM_TICKS 7.0
    void LogScaleFrame::config_log_scale (scaleStruct_t & scale)
    {
    wxASSERT (scale.max > scale.min && scale.min > 0.0)
    if (scale.type == mpLOG_TYPE_2DIGITS)
    {
    double a = log10 (scale.max / scale.min) / NUM_TICKS;
    for (size_t i=0; i<=NUM_TICKS; i++)
    {
    scale.vals [i] = scale.min * pow (10.0, a * i);
    scale.label [i].Printf (wxT("%2.1e"), scale.vals [i]);
    }
    scale.num_labels = NUM_TICKS;
    }
    else if (scale.max < 5.0e2 * scale.min) // 1, 2, 5, ... labels
    {
    scale.min_exp = floor (3.0 * log10 (scale.min)) / 3.0;
    scale.max_exp = ceil (3.0 * log10 (scale.max)) / 3.0;
    scale.delta = 1.0 / 3.0;
    scale.type = mpLOG_TYPE_1_2_5;
    }
    else if (scale.max < 1.0e4 * scale.min) // 1, 3, 10, ... labels
    {
    scale.min_exp = floor (2.0 * log10 (scale.min)) / 2.0;
    scale.max_exp = ceil (2.0 * log10 (scale.max)) / 2.0;
    scale.delta = 1.0 / 2.0;
    scale.type = mpLOG_TYPE_1_3_10;
    }
    else // exp10 (i, n+i, 2n+i, ... ) labels
    {
    scale.min_exp = floor (log10 (scale.min));
    scale.max_exp = ceil (log10 (scale.max));
    scale.delta = 1.0;
    while (scale.max > pow (10.0, 7.0 * scale.delta) * scale.min)
    scale.delta += 1.0;
    scale.type = mpLOG_TYPE_10n;
    }
    int n=0;
    for (double i=scale.min_exp; i<=scale.max_exp; i += scale.delta)
    {
    scale.vals [n] = pow (10.0, i);
    int exp = 0;
    while (scale.vals [n] < 1.0) scale.vals [n] = 10.0, exp--;
    while (scale.vals [n] >= 10.0) scale.vals [n] /= 10.0, exp++;
    scale.vals [n] = round (scale.vals [n]) * pow (10.0, exp);
    n++;
    }
    scale.num_labels = n;
    for (int n=0; n<scale.num_labels; n++)="" {="" wxASSERT="" (scale.vals="" <span="">[n] > 0.0);
    double mantissa = scale.vals [n];
    int exponent = 0;
    while (mantissa < 10.0) mantissa
    = 10.0, exponent--;
    while (mantissa >= 10.0) mantissa /= 10.0, exponent++;
    if (mpLOG_TYPE_10n == scale.type)
    scale.label[n].Printf (wxT("1e%+2d"), exponent);
    else
    scale.label[n].Printf (wxT("%de%+2d"), (int) round (mantissa), exponent);
    wxString temp;
    temp.Printf (wxT("config_log_scale - label [%d]: %s"), n, scale.label [n].c_str());
    err.LogText(temp);
    }
    }

     
    Last edit: Byron 2014-10-02

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks