То, что я пытаюсь сделать, это иметь график нормальности или «кривую колокола», как некоторые могут сказать, поверх гистограммы. Я использовал код для создания своей гистограммы и другой код для получения данных о нормальности, которые показаны ниже. На данный момент все, что я хочу знать, - это как объединить созданную мною гистограмму, используя код, и график гладких линий рассеяния XY (график нормальности), созданный вручную путем создания диаграммы с использованием данных нормальности, которые я получаю из кода.
Я попытался объединить их вместе, чтобы это выглядело так:
И, как вы можете видеть, график нормальности не совсем совпадает с гистограммой , Я обнаружил, что это из-за разницы в оси, которая вызывает его смещение. Мои данные о нормальности взяты из всех данных, а гистограмма использует значения счетчиков. Однако, когда я нахожу среднее значение и стандартное отклонение значений счетчика и изменяю данные в соответствии с ним, это происходит
При этом даже более смещен.
Код для гистограммы.
Sub MakeHistogram()
Dim src_sheet As Worksheet, Graph_sheet As Worksheet
Dim selected_range As Range
Dim r As Integer, firstOne As Integer
Dim percent_cell As Range
Dim num_percent As Integer
Dim count_range As Range, bin_range As Range
Dim new_chart As Chart
Dim lRow As Long
Dim RngToCover As Range, Chtob As ChartObject
Dim Snum As Long, Bnum As Long
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
.EnableEvents = False
.DisplayStatusBar = False
End With
With Sheets("Data")
lRow = .Cells(.Rows.Count, 1).End(xlUp).Row
Set selected_range = .Range(.Cells(2, 1), .Cells(lRow, 1))
End With
Set src_sheet = Sheets("Data")
Set Graph_sheet = Sheets("Graphs")
num_percent = selected_range.Count
' See how many bins we will have.
Const BIN_SIZE As Integer = 5
Dim num_bins As Integer
num_bins = 150 \ BIN_SIZE
' Make the bin separators.
Graph_sheet.Cells(1, 2) = "Bins"
For r = 1 To num_bins - 1
Graph_sheet.Cells(r + 2, 2) = r * BIN_SIZE
Next r
Graph_sheet.Cells(r + 2, 2) = 150
' Make the counts.
Graph_sheet.Cells(1, 1) = "Counts"
Set count_range = Graph_sheet.Range("A" & 3 & ":A" & num_bins + 2)
Set bin_range = Graph_sheet.Range("B" & 3 & ":B" & num_bins + 2)
count_range = WorksheetFunction.Frequency(selected_range, bin_range)
' Make the range labels.
Graph_sheet.Cells(1, 3) = "Ranges"
For r = 1 To num_bins
firstOne = 1
If r = 1 Then firstOne = 0
Graph_sheet.Cells(r + 2, 3) = "'" & _
(5 * (r - 1)) + firstOne & "-" & _
5 * (r - 1) + 5
Graph_sheet.Cells(r + 2, 3).HorizontalAlignment = _
xlRight
Next r
r = num_bins
Graph_sheet.Cells(r + 1, 3).HorizontalAlignment = xlRight
' Make the chart.
Set new_chart = Charts.Add()
With new_chart
.ChartType = xlColumnClustered
.SetSourceData Source:=Graph_sheet.Range("A" & 3 & ":A" & _
num_bins + 2), _
PlotBy:=xlColumns
.Location where:=xlLocationAsObject, _
Name:="Graphs"
End With
'Get the largest and smallest number
Bnum = WorksheetFunction.Max(selected_range.Value)
Snum = WorksheetFunction.Min(selected_range.Value)
With Graph_sheet
Set RngToCover = .Range(.Cells(6, 5), .Cells(23, 11))
End With
With ActiveChart
With .ChartArea.Format
' White background
.Fill.ForeColor.RGB = RGB(255, 255, 255)
' Red border
With .Line
.ForeColor.RGB = RGB(100, 100, 100)
.Weight = 2
End With
End With
.HasTitle = True
.ChartTitle.Characters.Text = title & " Histogram"
With .Axes(xlCategory, xlPrimary)
.HasTitle = True
.AxisTitle.Characters.Text = xStr
End With
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Count"
' Display percentage ranges on the X axis.
.SeriesCollection(1).XValues = "='" & _
"Graphs" & "'!R" & 3 & "C3:R" & _
num_bins + 2 & "C3"
Set Chtob = .Parent
Chtob.Height = RngToCover.Height
Chtob.Width = RngToCover.Width
Chtob.Top = RngToCover.Top
Chtob.Left = RngToCover.Left
.SeriesCollection(1).Select
With .ChartGroups(1)
.Overlap = 0
.GapWidth = 0
.HasSeriesLines = False
.VaryByCategories = False
End With
End With
'Add statistics
With Graph_sheet
r = num_bins + 4
.Cells(r, 1) = "Average"
.Cells(r, 2) = "=AVERAGE(Data!" & selected_range.Address & ")"
.Cells(r, 4) = "Min"
.Cells(r, 5) = Application.WorksheetFunction.Min(selected_range)
.Cells(r, 7) = "Q1"
.Cells(r, 8) = WorksheetFunction.Quartile(selected_range, 1)
.Cells(r, 10) = "Median"
.Cells(r, 11) = WorksheetFunction.Quartile(selected_range, 2)
r = r + 1
.Cells(r, 1) = "StdDev"
.Cells(r, 2) = "=STDEV(Data!" & selected_range.Address & ")"
.Cells(r, 4) = "Max"
.Cells(r, 5) = Application.WorksheetFunction.Max(selected_range)
.Cells(r, 7) = "Q3"
.Cells(r, 8) = WorksheetFunction.Quartile(selected_range, 3)
.Cells(r, 10) = "IQR"
.Cells(r, 11) = WorksheetFunction.Quartile(selected_range, 3) _
- WorksheetFunction.Quartile(selected_range, 1)
End With
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
.EnableEvents = True
.DisplayStatusBar = True
End With
Graph_sheet.Columns(1).AutoFit
End Sub
Код для получения точек осей x и y графика нормальности, которые могут создать плавную линию графика рассеяния XY для построения графика нормальности.
Sub GetNormalityData()
Dim xMean As Variant
Dim xSigma As Variant
Dim xFirst As Variant
Dim xLast As Variant
Dim Nstep As Long
Dim X As Variant
Dim y As Variant
Dim sRow As Long
Dim StepValue As Variant
' enter values of mean, sigma, xfirst, xlast, Nstep
With ActiveSheet
xMean = .Range("B1")
xSigma = .Range("B2")
xFirst = .Range("B3")
xLast = .Range("B4")
Nstep = .Range("B5")
End With
StepValue = (xLast - xFirst) / (Nstep - 1)
sRow = 0
X = xFirst
With Range("D1")
Do While X <= xLast
.Offset(sRow, 0) = X
y = Application.WorksheetFunction.NormDist(X, xMean, xSigma, False)
.Offset(sRow, 1) = y
X = X + StepValue
sRow = sRow + 1
Loop
End With
End Sub
Я также приложил пример рабочей книги на случай, если вам понадобится здесь . Чтобы получить графики, я сначала создал диаграмму нормального графика, а затем скопировал в нее значения числа гистограмм и изменил их на столбчатый кластерный график. Если есть какие-либо вопросы, которые вы хотите задать, пожалуйста, не стесняйтесь.