Search code examples
c#winformsheatmapoxyplot

Use a DateTime axis for an Oxyplot HeatMap


I want to use a datetimeaxis for the Y-axis of an Oxyplot heatmapseries (in winforms). The API allows me to add the axis to the PlotModel, but does not do much good since the y-value is mapped off of the integral column index of a matrix of doubles - the y values come out to around Jan. 1900.

How can I use times for the y data on the heat map?


Solution

  • The workaround to make this happen is not too difficult. When setting up the chart, create 2 axes: one for the time, and another for the integral index of the HeatMapSeries input.

    DateTimeAxis dateTimeAxis;
    HeatMapSeries series;
    ....
    
    //set up the time axis for y
    dateTimeAxis = new DateTimeAxis();
    dateTimeAxis.Position = AxisPosition.Left;
    dateTimeAxis.Key = "dateTimeAxis";                        
    plotModel.Axes.Add(dateTimeAxis);
    
    //set up a shadow axis for the HeatMapSeries
    var linearAxis = new LinearAxis();
    linearAxis.Position = AxisPosition.Left;
    linearAxis.Key = "linearAxis";
    plotModel.Axes.Add(linearAxis);
    series.YAxisKey = linearAxis.Key;
    

    Next, the assigned y-axis will have to be hidden - but we can't access the YAxis property until the plot has been updated:

    //hide the linear axis
    plotModel.Updated += (sender, e) =>
    {
        series.YAxis.IsAxisVisible = false;
    };
    

    Finally, when setting the heat map data, simply create the desired mapping from the matrix index to time. Then adjust the y-scale. For example:

    public void UpdateData(double[,] data)
    {
        series.Data = data;
    
        //adjust date/time axis
        int numOfMinutes = data.GetLength(1);            
        dateTimeAxis.Minimum = DateTimeAxis.ToDouble(DateTime.Now);
        dateTimeAxis.Maximum DateTimeAxis.ToDouble(DateTime.Now.AddMinutes(numOfMinutes));
     }
    

    I have not yet seen a way to do this directly in OxyPlot