public static ISeries[] CreateSeries(double[][] data, string[] labels, BaseOptions options)
        {
            ISeries[] series;

            switch (options.PlotType)
            {
            case PlotType.Line:
                series = data.Skip(options.Skip).Take(options.NumToShow).Select(
                    (ia, i) => (ISeries)(new ErrorLineSeries
                {
                    Label = labels?[i],
                    X = ia,
                    Row = i / options.Subplots.Columns,
                    Column = i % options.Subplots.Columns
                })).ToArray();
                break;

            case PlotType.Bar:
                series = data.Skip(options.Skip).Take(options.NumToShow).Select(
                    (ia, i) => (ISeries)(new BarSeries <string>
                {
                    Label = labels?[i],
                    DependentValues = ia,
                    Row = i / options.Subplots.Columns,
                    Column = i % options.Subplots.Columns
                })).ToArray();
                break;

            default:
                throw new ArgumentException("Unknonw plot type", nameof(options.PlotType));
            }

            return(series);
        }
        /// <summary>
        /// Plots the images.
        /// </summary>
        /// <param name="imagesFlat">Images.</param>
        /// <param name="title">The title.</param>
        /// <param name="options">Plotting options.</param>
        public static void PlotImages(Matrix imagesFlat, string title, BaseOptions options)
        {
            var series =
                (from t in imagesFlat.EnumerateRowsIndexed()
                 let index = t.Item1
                             let image = Reshape(t.Item2)
                                         select
                                         new MatrixSeries
            {
                Values = image,
                Row = index / options.Subplots.Columns,
                Column = index % options.Subplots.Columns
            }
                ).Cast <ISeries>().ToList();

            var plotter = new Plotter
            {
                Title      = title,
                Series     = series,
                Grid       = false,
                Subplots   = options.Subplots,
                Python     = PythonPath,
                ScriptName = Path.Combine(ScriptPath, "EffectOfBases"),
                FigureName = Path.Combine(FigurePath, "EffectOfBases"),
                Show       = options.Show
            };

            plotter.Plot();
        }
        ISeries[] CreateSeries <T>(T[][] data, string[] labels, BaseOptions options)
            where T : IDistribution <double>, CanGetMean <double>, CanGetVariance <double>
        {
            ISeries[] series;

            switch (options.PlotType)
            {
            case PlotType.ErrorLine:
                series = data.Skip(options.Skip).Take(options.NumToShow).Select(
                    (ia, i) => (ISeries)(new ErrorLineSeries
                {
                    Label = labels?[i],
                    X = ia.Select(x => x.GetMean()).ToArray(),
                    ErrorValues = ia.GetStandardDeviations(),
                    Row = i / options.Subplots.Columns,
                    Column = i % options.Subplots.Columns
                })).ToArray();
                break;

            case PlotType.Bar:
                series = data.Skip(options.Skip).Take(options.NumToShow).Select(
                    (ia, i) => (ISeries)(new BarSeries <string>
                {
                    Label = labels?[i],
                    DependentValues = ia.GetMeans(),
                    Row = i / options.Subplots.Columns,
                    Column = i % options.Subplots.Columns
                })).ToArray();
                break;

            case PlotType.ErrorBar:
                series = data.Skip(options.Skip).Take(options.NumToShow).Select(
                    (ia, i) => (ISeries)(new BarSeries <string>
                {
                    Label = labels?[i],
                    DependentValues = ia.GetMeans(),
                    ErrorValues = ia.GetStandardDeviations(),
                    Row = i / options.Subplots.Columns,
                    Column = i % options.Subplots.Columns
                })).ToArray();
                break;

            case PlotType.Line:
                series = data.Skip(options.Skip).Take(options.NumToShow).Select(
                    (ia, i) => (ISeries)(new LineSeries
                {
                    Label = labels?[i],
                    X = ia.GetMeans(),
                    Row = i / options.Subplots.Columns,
                    Column = i % options.Subplots.Columns
                })).ToArray();
                break;

            default:
                throw new ArgumentException("Unknonw plot type", nameof(options.PlotType));
            }

            return(series);
        }
        // /// <summary>
        // /// Plots the reconstructions.
        // /// </summary>
        // /// <returns>The reconstructions.</returns>
        // /// <param name="signals">Signals.</param>
        // /// <param name="reconstructions">Reconstructions.</param>
        // /// <param name="title">Title.</param>
        // /// <param name="numToShow">Number to show.</param>
        // /// <param name="rows">Rows.</param>
        // /// <param name="cols">Cols.</param>
        // /// <param name="subTitle">Sub title.</param>
        // public static void PlotReconstructions(double[][] signals, double[][] reconstructions, string title, int numToShow, int rows, int cols, string subTitle = null)
        // {
        //     var r = signals.Zip(reconstructions, (s, e) => new Reconstruction { Signal = s, Estimate = e.Select(Gaussian.PointMass).ToArray() }).ToArray();
        //     PlotReconstructions(r, averageError, title, numToShow, rows, cols, subTitle);
        // }

        /// <summary>
        /// Plots the posteriors.
        /// </summary>
        /// <returns>The posteriors.</returns>
        /// <param name="posteriors">Posteriors.</param>
        /// <param name="title">Title.</param>
        /// <param name="subTitle">Sub title.</param>
        /// <param name="options">Plot options.</param>
        public static void PlotPosteriors <T>(
            T[][] posteriors,
            string title,
            string subTitle,
            BaseOptions options)
            where T : IDistribution <double>, CanGetMean <double>, CanGetVariance <double>
        {
            var series = CreateSeries(posteriors, null, options);

            // var series = new[] { new LineSeries { X = x1, Row = 0 }, new LineSeries { X = x2, Row = 1 } };
            string sub     = string.IsNullOrEmpty(subTitle) ? string.Empty : $"_{subTitle.Replace(" ", "_")}";
            string sel     = $"{options.Skip}-{options.Skip + options.NumToShow}";
            var    plotter = new Plotter
            {
                Title      = $"{title} {sel}",
                XLabel     = "x", YLabel = "y", Series = series, Subplots = options.Subplots,
                Python     = PythonPath,
                ScriptName = Path.Combine(ScriptPath, $"{title}{sub}_{sel}.py"),
                FigureName = Path.Combine(FigurePath, $"{title}{sub}_{sel}.pdf"),
                Show       = options.Show
            };

            plotter.Plot();
        }
        public static void PlotImages(Gaussian[][] images, int imageWidth, string title, BaseOptions options)
        {
            var dictionary = Matrix.Build.DenseOfRowArrays(images.GetMeans <Gaussian>());

            PlotImages(dictionary.SubMatrix(0, options.Subplots.Rows * options.Subplots.Columns, 0, imageWidth), title, options);
        }