Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Histogram / column chart not showing bars all the way to the bottom

I'm trying to plot a histogram using the C# .NET Chart control (System.Windows.Forms.DataVisualization.Charting).

I have it set up as a Column chart. The data is retrieved via a Histogram object using the NMath libraries, so it does all the sorting into bins and such. Everything looks fine until I switch the y axis to a log scale. To get things to even show up, I set the DataPoint of any bin with 0 entries to have a y-value of 0.001 instead of 0. I then set the minimum of the y axis to 0.1 and the max to something beyond the biggest bin. The result is that all of the columns start at a y-value of 1 instead of at the minimum. Any bin with 0 entries has a column which extends downward (toward the 0.001). Screenshot available here

The code which sets the min/max/intervals on the axis is below.

double ymin = FindMinimumYValue();
double mag = Math.Floor(Math.Log10(ymin));
ymin = Math.Pow(10, mag);
yAxis.Minimum = ymin;
double ymax = FindMaximumYValue();
mag = Math.Ceiling(Math.Log10(ymax));
ymax = Math.Pow(10, mag);
yAxis.Maximum = ymax;

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

I'm probably not setting a property on the axis I need to, but is there a way to have the columns all extend upward from the minimum on the y axis, even if that minimum is less than 1?

ETA: If I remove the DataPoints with 0 counts from the Series, I no longer get the downward bars between 0.1 and 1. But, all the other bars still start at 1 and go upwards, instead of starting at the minimum.

ETA again: I'm thinking I could use a RangeColumn type of chart, and specify the min and max y values for each bin. That doesn't seem very elegant, as I'll need to change between RangeColumn and Column type when the user switches the axis to log mode and back, or keep adjusting the minimum y value of the RangeColumn data points (from 0 to 0.1 and back). And that seems like more of a workaround and not a solution.

like image 298
mmathis Avatar asked Feb 06 '14 19:02

mmathis


1 Answers

A workaround would be to add a datapoint with Y value 0 for each x value.

    Series = chart1.Series.Add("Test");
    Axis yAxis = chart1.ChartAreas[0].AxisY;
    yAxis.IsLogarithmic = true;
    double ymin = 0.1;
    yAxis.Minimum = ymin;
    double ymax = 100;
    yAxis.Maximum = ymax;

    Series.Points.Add(new DataPoint(1, 3));
    Series.Points.Add(new DataPoint(1, 0));
    Series.Points.Add(new DataPoint(2, 3));
    Series.Points.Add(new DataPoint(2, 0));
    Series.Points.Add(new DataPoint(3, 4));
    Series.Points.Add(new DataPoint(3, 0));
    Series.Points.Add(new DataPoint(4, 5));
    Series.Points.Add(new DataPoint(4, 0));
like image 57
David Avatar answered Nov 08 '22 00:11

David