0
votes

I want to create decade logarithm y axis as shown in the first picture. The first picture has 78 as minimum value of logarithm y-axis. Then it shows other axis values in the power of 10 like 100 and 1000. At the end, it shows maximum value of logarithm y-axis This first graph is not developed using MS Chart control.

The graph in second picture is developed using MS Chart control. In the second graph, i am not able to show axis values in the power of 10 such as 100 and 1000 similar to the first graph. I am using below code to create this graph.

    axis.MinorGrid.Interval = 1;
    axis.MinorTickMark.Interval = 1;
    axis.MajorGrid.Interval = 1;
    axis.MajorTickMark.Interval = 1;

I want to create second graph similar to the first graph

Desired log y axis

log y axis using MS Chart

1

1 Answers

0
votes

After quite an effort, i found the solution to this problem. In order to show logarithmic y-axis values in power of 10, interval offset needs to be set for the labels. Major grid and minor grid can also be set accordingly. For example, in picture 2, the minimum is 78.53. So if we want to show 100, we need to set an offset of 21.47. To calculate the offset, i have to perform the calculation

100 - 78.53 = 21.47.

Now since we are dealing with logarithmic values of y-axis, we need to perform this calculation in logarithmic values

Offset = log(100) - log(78.53)

If we set the above offset in picture 2 to axis label style, major and minor grids, then the first label and grid will start from 100 followed by 1000, 100000 as we needed. Intervals for label style, major and minor grids should be set to 1, which indicates 1 decade.

Now the second problem is how to show the minimum and maximum values of the graph. By default, MS Chart will not show these values. We need to work on custom labels to show minimum and maximum values as well as the values that occur in between i.e. 10, 100, 1000 etc because If we add custom labels, then we need to handle the labeling of the axis all by ourselves.

Below is the code which creates the above desired graph.

            chart1.Series.Clear();
            chart1.ChartAreas[0].AxisY.CustomLabels.Clear();
            chart1.Series.Add("FirstSeries");

            // Set the type to line      
            chart1.Series["FirstSeries"].ChartType = SeriesChartType.Line;

            // Color the line of the graph light green and give it a thickness of 3
            chart1.Series[0].Color = Color.Red;
            chart1.Series[0].BorderWidth = 1;

            int minimum = 7, maximum = 300;
            chart1.ChartAreas[0].AxisY.Minimum = minimum;
            chart1.ChartAreas[0].AxisY.Maximum = maximum;
            double logMin = Math.Log(chart1.ChartAreas[0].AxisY.Minimum, 10);

            //If minimum starts from log(7) = 0.845 then take 1 which is equivalent to 100 in normal mode.
            double ceilMin = Math.Ceiling(logMin);
            double logMax = Math.Log(chart1.ChartAreas[0].AxisY.Maximum, 10);

            chart1.ChartAreas[0].AxisY.MajorGrid.Enabled = true;
            chart1.ChartAreas[0].AxisY.MinorGrid.Enabled = true;
            chart1.ChartAreas[0].AxisY.MajorTickMark.Enabled = true;
            chart1.ChartAreas[0].AxisY.MinorTickMark.Enabled = true;

            double intervalOffset = ceilMin - logMin;
            chart1.ChartAreas[0].AxisY.LabelStyle.IntervalOffset = intervalOffset;
            chart1.ChartAreas[0].AxisY.MajorGrid.IntervalOffset = intervalOffset;
            chart1.ChartAreas[0].AxisY.MinorGrid.IntervalOffset = intervalOffset;
            chart1.ChartAreas[0].AxisY.MajorTickMark.IntervalOffset = intervalOffset;
            chart1.ChartAreas[0].AxisY.MinorTickMark.IntervalOffset = intervalOffset;

            //Setting intervals
            chart1.ChartAreas[0].AxisY.MajorGrid.Interval = 1;
            chart1.ChartAreas[0].AxisY.MajorTickMark.Interval = 1;
            chart1.ChartAreas[0].AxisY.MinorGrid.Interval = 1;
            chart1.ChartAreas[0].AxisY.MinorTickMark.Interval = 1;
            chart1.ChartAreas[0].AxisY.LabelStyle.Interval = 1;

            for (int x = minimum; x <= maximum; x += 1)
            {
                chart1.Series[0].Points.Add(x, x);
            }

            //Adding custom labels for powers of 10 for example 1,10,100 
            for (double x = minimum; x <= maximum; x+=1)
            {
                double logX = Math.Log10(x);
                double floorX = Math.Floor(logX);
                if (logX - floorX == 0)
                    chart1.ChartAreas[0].AxisY.CustomLabels.Add(logX-0.05, logX + 0.05, "" + Math.Pow(10, logX), 0, LabelMarkStyle.None);
            }

            //Adding minimum and maximum label. 0.05 factor is added by experiment.
            chart1.ChartAreas[0].AxisY.CustomLabels.Add(logMin-0.05, logMin + 0.05, "" + chart1.ChartAreas[0].AxisY.Minimum, 0, LabelMarkStyle.None);
            chart1.ChartAreas[0].AxisY.CustomLabels.Add(logMax-0.05, logMax+0.05, "" + chart1.ChartAreas[0].AxisY.Maximum, 0, LabelMarkStyle.None);

            chart1.ChartAreas[0].AxisY.IsLogarithmic = true;