echarts:如何在条形图上添加正态分布曲线?
echarts: How can I add a normal distribution curve on bar chart?
我用echarts绘制了条形图:
如何在下图所示的条形图线上显示正态分布曲线:
export class MainComponent implements OnInit, AfterViewInit, OnDestroy {
binsCount: number = 20;
histogramDetails: any = [];
//#endregion
constructor(private router: Router,
private store: Store<any>,
private projectService: ProjectService,
private taskService: TaskService,
private messageService: MessageService, ) { }
async createNewPlot(task: Task) {
if(this.selectedPlotType.name === 'Histogram') {
plotOption = await this.loadHistogramPlotData(task) ;
}
}
loadHistogramPlotData(task) {
if (!task || !this.selectedVariableX) {
return
}
return new Promise((resolve, reject) => {
this.taskService.getOutputVariablesHistogramPlot(task.id, this.selectedVariableX.id).subscribe(
response => {
//reset data
log.debug(`response = ${JSON.stringify(response)}`);
const plotData = this.setHistogramDetails(response.hist_plot_data);
resolve(plotData);
},
error => {
log.error(error);
reject(error)
}
);
})
}
setHistogramDetails(histogramDetails: any) {
// histogramDetails ? this.histogramDetails.push(histogramDetails) : null ;
const nums = histogramDetails.realization
let min = Math.floor(Math.min(...nums));
let max = Math.ceil(Math.max(...nums));
const binSize = (max - min) / this.binsCount;
let xaxisData: number[] = [];
let yseries = [];
let previousNumber = min;
for (let i = 0; i <= this.binsCount; i++) {
xaxisData.push(parseFloat(previousNumber.toFixed(1)));
yseries.push(0);
previousNumber = previousNumber + binSize;
}
for (const num of nums) {
for (let i = 1; i < xaxisData.length; i++) {
if (num < xaxisData[i]) {
yseries[i]++;
break;
}
}
}
const plotData: number[] = yseries;
const options = {
grid: {
left: 30,
top: 10,
bottom: 100
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#eee'
}
}
},
legend: {
orient: 'vertical',
left: '5%',
bottom: 30,
itemHeight: 3,
itemGap: 14,
textStyle: {
fontSize: 10,
color: '#333333'
},
data: ['Specified Distribution', 'Simulated Distribution']
},
xAxis: [
{
type: 'category',
data: [xaxisData[0] * 10, ...xaxisData, xaxisData[xaxisData.length - 1] * 10],
boundaryGap: ['40%', '40%'],
axisTick: {
alignWithLabel: true
},
axisPointer: {
type: 'shadow'
}
}
],
yAxis: [
{
type: 'value',
splitNumber: 5,
axisLabel: {
formatter: '{value}',
fontSize: 10
}
}
],
dataZoom: [{
type: 'inside',
throttle: 50
}],
series: [
{
name: 'Simulated Distribution',
type: 'bar',
color: '#2DA8D8',
large: true,
data: plotData,
}
],
histogramDetails: histogramDetails
};
return options;
};
}
Echarts 没有built-in函数正态分布。您需要 calculate it based on your data and add like usual line
series 或 MarkLine
才能显示栏。
添加正态分布是 echarts-stat
库中一个未解决的 Github 问题:
https://github.com/ecomfe/echarts-stat/issues/4
你也可以使用这个:
function normalDist(theta, x) {
return 1 / (theta * Math.sqrt(2 * Math.PI)) * Math.exp(- x * x / 2 / theta / theta);
}
我用echarts绘制了条形图:
如何在下图所示的条形图线上显示正态分布曲线:
export class MainComponent implements OnInit, AfterViewInit, OnDestroy {
binsCount: number = 20;
histogramDetails: any = [];
//#endregion
constructor(private router: Router,
private store: Store<any>,
private projectService: ProjectService,
private taskService: TaskService,
private messageService: MessageService, ) { }
async createNewPlot(task: Task) {
if(this.selectedPlotType.name === 'Histogram') {
plotOption = await this.loadHistogramPlotData(task) ;
}
}
loadHistogramPlotData(task) {
if (!task || !this.selectedVariableX) {
return
}
return new Promise((resolve, reject) => {
this.taskService.getOutputVariablesHistogramPlot(task.id, this.selectedVariableX.id).subscribe(
response => {
//reset data
log.debug(`response = ${JSON.stringify(response)}`);
const plotData = this.setHistogramDetails(response.hist_plot_data);
resolve(plotData);
},
error => {
log.error(error);
reject(error)
}
);
})
}
setHistogramDetails(histogramDetails: any) {
// histogramDetails ? this.histogramDetails.push(histogramDetails) : null ;
const nums = histogramDetails.realization
let min = Math.floor(Math.min(...nums));
let max = Math.ceil(Math.max(...nums));
const binSize = (max - min) / this.binsCount;
let xaxisData: number[] = [];
let yseries = [];
let previousNumber = min;
for (let i = 0; i <= this.binsCount; i++) {
xaxisData.push(parseFloat(previousNumber.toFixed(1)));
yseries.push(0);
previousNumber = previousNumber + binSize;
}
for (const num of nums) {
for (let i = 1; i < xaxisData.length; i++) {
if (num < xaxisData[i]) {
yseries[i]++;
break;
}
}
}
const plotData: number[] = yseries;
const options = {
grid: {
left: 30,
top: 10,
bottom: 100
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#eee'
}
}
},
legend: {
orient: 'vertical',
left: '5%',
bottom: 30,
itemHeight: 3,
itemGap: 14,
textStyle: {
fontSize: 10,
color: '#333333'
},
data: ['Specified Distribution', 'Simulated Distribution']
},
xAxis: [
{
type: 'category',
data: [xaxisData[0] * 10, ...xaxisData, xaxisData[xaxisData.length - 1] * 10],
boundaryGap: ['40%', '40%'],
axisTick: {
alignWithLabel: true
},
axisPointer: {
type: 'shadow'
}
}
],
yAxis: [
{
type: 'value',
splitNumber: 5,
axisLabel: {
formatter: '{value}',
fontSize: 10
}
}
],
dataZoom: [{
type: 'inside',
throttle: 50
}],
series: [
{
name: 'Simulated Distribution',
type: 'bar',
color: '#2DA8D8',
large: true,
data: plotData,
}
],
histogramDetails: histogramDetails
};
return options;
};
}
Echarts 没有built-in函数正态分布。您需要 calculate it based on your data and add like usual line
series 或 MarkLine
才能显示栏。
添加正态分布是 echarts-stat
库中一个未解决的 Github 问题:
https://github.com/ecomfe/echarts-stat/issues/4
你也可以使用这个:
function normalDist(theta, x) {
return 1 / (theta * Math.sqrt(2 * Math.PI)) * Math.exp(- x * x / 2 / theta / theta);
}