The following example shows how to plot an XY series with a histogram in the same chart:
In this example, a Line series displays a normal distribution curve on the secondary axis and is aligned with a histogram on the primary axis.
View Example: How to: Plot an XY Series with a Histogram in a Chart
using System;
using System.Collections.ObjectModel;
using System.Windows;
namespace SideBySideBar2DChart {
public partial class Window1 : Window {
public Window1() {
InitializeComponent();
}
}
public class ViewModel {
const int HistogramPointsCount = 1000;
const int DistributionPointsCount = 100;
const double Mean = 0.5;
const double StdDev = 0.15;
const double Max = 10;
Random random = new Random();
public ObservableCollection<DataPoint> NormalDistribution { get; private set; }
public ObservableCollection<DataPoint> Histogram { get; private set; }
public double MinValue { get { return 0; } }
public double MaxValue { get { return Max; } }
public double BinCount { get { return 20; } }
public ViewModel() {
CreateDataSource();
}
void CreateDataSource() {
NormalDistribution = new ObservableCollection<DataPoint>();
for(int i = 0; i < DistributionPointsCount; i++) {
double x = i * Max / DistributionPointsCount;
NormalDistribution.Add(new DataPoint(x, GetNormalDistribution(x, Mean * Max, StdDev * Max)));
}
Histogram = new ObservableCollection<DataPoint>();
for(int x = 0; x < HistogramPointsCount; x++)
Histogram.Add(new DataPoint(GenerateHistogramPoint(Mean * Max, StdDev * Max)));
}
double GetNormalDistribution(double x, double mean, double stdDev) {
double tmp = 1 / (Math.Sqrt(2 * Math.PI) * stdDev);
return Math.Exp(-Math.Pow(x - mean, 2) / (2 * Math.Pow(stdDev, 2))) * tmp;
}
double GenerateHistogramPoint(double mean, double stdDev) {
return Math.Sqrt(-2 * Math.Log(random.NextDouble())) * Math.Cos(2 * Math.PI * random.NextDouble()) * stdDev + mean;
}
}
}
Imports System
Imports System.Collections.ObjectModel
Imports System.Windows
Namespace SideBySideBar2DChart
Partial Public Class Window1
Inherits Window
Public Sub New()
InitializeComponent()
End Sub
End Class
Public Class ViewModel
Private Const HistogramPointsCount As Integer = 1000
Private Const DistributionPointsCount As Integer = 100
Private Const Mean As Double = 0.5
Private Const StdDev As Double = 0.15
Private Const Max As Double = 10
Private random As New Random()
Private privateNormalDistribution As ObservableCollection(Of DataPoint)
Public Property NormalDistribution() As ObservableCollection(Of DataPoint)
Get
Return privateNormalDistribution
End Get
Private Set(ByVal value As ObservableCollection(Of DataPoint))
privateNormalDistribution = value
End Set
End Property
Private privateHistogram As ObservableCollection(Of DataPoint)
Public Property Histogram() As ObservableCollection(Of DataPoint)
Get
Return privateHistogram
End Get
Private Set(ByVal value As ObservableCollection(Of DataPoint))
privateHistogram = value
End Set
End Property
Public ReadOnly Property MinValue() As Double
Get
Return 0
End Get
End Property
Public ReadOnly Property MaxValue() As Double
Get
Return Max
End Get
End Property
Public ReadOnly Property BinCount() As Double
Get
Return 20
End Get
End Property
Public Sub New()
CreateDataSource()
End Sub
Private Sub CreateDataSource()
NormalDistribution = New ObservableCollection(Of DataPoint)()
For i As Integer = 0 To DistributionPointsCount - 1
Dim x As Double = i * Max / DistributionPointsCount
NormalDistribution.Add(New DataPoint(x, GetNormalDistribution(x, Mean * Max, StdDev * Max)))
Next i
Histogram = New ObservableCollection(Of DataPoint)()
For x As Integer = 0 To HistogramPointsCount - 1
Histogram.Add(New DataPoint(GenerateHistogramPoint(Mean * Max, StdDev * Max)))
Next x
End Sub
Private Function GetNormalDistribution(ByVal x As Double, ByVal mean As Double, ByVal stdDev As Double) As Double
Dim tmp As Double = 1 / (Math.Sqrt(2 * Math.PI) * stdDev)
Return Math.Exp(-Math.Pow(x - mean, 2) / (2 * Math.Pow(stdDev, 2))) * tmp
End Function
Private Function GenerateHistogramPoint(ByVal mean As Double, ByVal stdDev As Double) As Double
Return Math.Sqrt(-2 * Math.Log(random.NextDouble())) * Math.Cos(2 * Math.PI * random.NextDouble()) * stdDev + mean
End Function
End Class
End Namespace
<Window
x:Class="SideBySideBar2DChart.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dxc="http://schemas.devexpress.com/winfx/2008/xaml/charts"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:local="clr-namespace:SideBySideBar2DChart"
Width="820.806"
Height="354.032"
DataContext="{dxmvvm:ViewModelSource Type=local:ViewModel}"
Title="WPF Chart">
<Grid>
<dxc:ChartControl Name="chartControl1">
<dxc:ChartControl.Diagram>
<dxc:XYDiagram2D x:Name="diagram">
<dxc:XYDiagram2D.AxisX>
<dxc:AxisX2D Name="primaryAxisX" Visible="True">
<dxc:AxisX2D.WholeRange>
<dxc:Range
MaxValue="{Binding MaxValue}"
MinValue="{Binding MinValue}"
SideMarginsValue="0" />
</dxc:AxisX2D.WholeRange>
<dxc:AxisX2D.NumericScaleOptions>
<dxc:CountIntervalNumericScaleOptions
Count="{Binding BinCount}"
GridLayoutMode="GridShiftedLabelCentered"
Pattern="{}{OB}{A1:F1}, {A2:F1}{CB}" />
</dxc:AxisX2D.NumericScaleOptions>
</dxc:AxisX2D>
</dxc:XYDiagram2D.AxisX>
<dxc:XYDiagram2D.SecondaryAxesX>
<dxc:SecondaryAxisX2D Name="secondaryAxisX" Visible="False">
<dxc:SecondaryAxisX2D.NumericScaleOptions>
<dxc:ContinuousNumericScaleOptions />
</dxc:SecondaryAxisX2D.NumericScaleOptions>
<dxc:SecondaryAxisX2D.WholeRange>
<dxc:Range SideMarginsValue="0" />
</dxc:SecondaryAxisX2D.WholeRange>
</dxc:SecondaryAxisX2D>
</dxc:XYDiagram2D.SecondaryAxesX>
<dxc:XYDiagram2D.SecondaryAxesY>
<dxc:SecondaryAxisY2D Name="secondaryAxisY" />
</dxc:XYDiagram2D.SecondaryAxesY>
<dxc:XYDiagram2D.Series>
<dxc:BarStackedSeries2D
AggregateFunction="Histogram"
ArgumentDataMember = "XValue"
ArgumentScaleType="Numerical"
BarWidth="1"
DataSource="{Binding Histogram}"
DisplayName="Histogram" />
<dxc:SplineSeries2D
AggregateFunction="None"
ArgumentDataMember = "XValue"
ArgumentScaleType="Numerical"
AxisX="{Binding ElementName=secondaryAxisX}"
AxisY="{Binding ElementName=secondaryAxisY}"
DataSource="{Binding NormalDistribution}"
DisplayName="Normal Distribution"
ValueDataMember = "YValue" />
</dxc:XYDiagram2D.Series>
</dxc:XYDiagram2D>
</dxc:ChartControl.Diagram>
</dxc:ChartControl>
</Grid>
</Window>
See Also