Display tick labels in logarithmic scale MS Chart (log-log)
Solution 1:
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";
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..
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!