echarts: How can I add a normal distribution curve on bar chart?

Viewed 1207

I have plotted bar chart using echarts:

enter image description here

How can I show a normal distribution curve on bar chart line shown in the below image:

enter image description here

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;
  };

}
1 Answers

Echarts has no built-in function normal distribution. You need to calculate it based on your data and add like usual line series or MarkLine for bar.

Adding normal distribution is an open Github issue on the echarts-stat library: https://github.com/ecomfe/echarts-stat/issues/4

Also you can use this:

function normalDist(theta, x) {
  return 1 / (theta * Math.sqrt(2 * Math.PI)) * Math.exp(- x * x / 2 / theta / theta);
}

Related