Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
741 views
in Technique[技术] by (71.8m points)

c# - Display tick labels in logarithmic scale MS Chart (log-log)

I have a plot created with MS Charts in Visual Studio 2015 (C#) with logarithmic scales (both axes) (see figure).

I need to add more grid lines and the corresponding labels in the x-axis. I want to label each minor tick between 1 (2, 3, 4...) and 10 and between 10 and 100 (20, 30, 40...) and, also, I want to add grid lines between e.g. 10 and 20.

I used the Interval of 1 for the label in the axes properties of the chart but it didn't work.

Chart with log scale

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

After(!) adding a point at a non-zero x-value or setting chart.SuppressExceptions = true you can use these properties for a Chartarea ca:

ca.AxisX.IsLogarithmic = true;
ca.AxisX.LogarithmBase = 10;

// with 10 as the base it will go to 1, 10, 100, 1000..
ca.AxisX.Interval = 1;

// this adds 4 tickmarks into each interval:
ca.AxisX.MajorTickMark.Interval = 0.25;

// this add 8 gridlines into each interval:
ca.AxisX.MajorGrid.Interval = 0.125;

// this sets two i.e. adds one extra label per interval
ca.AxisX.LabelStyle.Interval = 0.5;
ca.AxisX.LabelStyle.Format = "#0.0";

enter image description here

Update:

Since you don't want to have automatic labels (which are always aligned by value) you need to add CustomLabels.

For this you need to set up a list of positions/values where you want a label to show:

    // pick a better name!
    List<double> xs = new List<double>() { 1, 2, 3, 4, 5, 10, 20, 50, 100, 200, 500, 1000};

Next we need to assign a FromPosition and a ToPosition to each CustomLabel we create. This is always a little tricky but here even more than usual..

The two values need to be spaced far enough to allow a label to fit in.. So we pick a spacer-factor:

    double spacer = 0.9d;

And we also turn off the auto-fitting mechanism:

    ca.AxisX.IsLabelAutoFit = false;

Now we can add the CustomLabels:

    for (int i = 0; i < xs.Count; i++)
    {
        CustomLabel cl = new CustomLabel();
        if (xs[i] == 1 || xs[i] <= 0)
        {
            cl.FromPosition = 0f;
            cl.ToPosition = 0.01f;
        }
        else
        {
            cl.FromPosition = Math.Log10(xs[i] * spacer);
            cl.ToPosition = Math.Log10(xs[i] / spacer);
        }

        cl.Text = xs[i] + "";
        ca.AxisX.CustomLabels.Add(cl);

    }

As you can see we need to calculate the values using the Log10 function that is applied to the Axis and the spacing is achieved by multiplying/dividing the spacer, not by adding. The spacing value must also be scaled by Log10 and is included in the function.

We also need to take care of the case of a value of 1, which amounts to a label position of 0; but this won't result in any spacing when multiplying/dividing it. So we set a suitable ToPosition manually.

I wish I knew of an easier way to do this, but as the list of label positions is really your choice, I doubt there is a short-cut..

enter image description here

I have added points at 40 and 50 to show how one label matches.. Also note how the label positions are somewhat mixed. Feel free to use yours!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...