Thursday, 27 January 2022

python - matplot lib sub-plot grid: where to insert row/column arguments

For context, I'm working with SKLearn's text analysis topic extraction documentation script for displaying the top words for a given fit. But my actual issue is toggling matplotlib.

How to reference sub-plot row/column locations?

Extracting subplot coordinates in Python

This question asks about coordinates of subplots, but I can't find a way to use this info to help me with my for loop, which is supposed to plot the top words from a list of data inputs (running the model with different data at each iteration and plotting results in a distinct sub plot):

tf_list = [cm_array, xb_array, array_3, array_4, array_5, array_6, array_7]

for i in range(enumerate(tf_list)):
    tf = tf_vectorizer.fit_transform(tf_list[i])
    n_components = 1
    lda.fit(tf)
    n_top_words = 20
    tf_feature_names = tf_vectorizer.get_feature_names_out()
    top_word_comparison(lda, tf_feature_names, n_top_words, "Topics in LDA model")

I think this should work in theory, but the trouble is I can't figure out how to change the documentation's plot function to incorporate different fits. The furthest I got (with the help of Alex):

   def top_word_comparison(axes, model, feature_names, n_top_words, subplot_title):
    #column logic
    for j in range(len(tf_list)):
        top_features_ind = model.components_.argsort()[: -n_top_words - 1 : -1]
        top_features = [feature_names[i] for i in top_features_ind]
        weights = model.components_[top_features_ind]
        
        #print(len(model.components_))
        print(weights)
        ax = axes[j]
        ax.barh(top_features, weights, height=0.7)
        ax.set_title(subplot_title, fontdict={"fontsize": 30})
        ax.invert_yaxis()
        ax.tick_params(axis="both", which="major", labelsize=20)
        for i in "top right left".split():
            ax.spines[i].set_visible(False)

#tf_list = [cm_array, xb_array]
fig, axes = plt.subplots(2, 5, figsize=(30, 15), sharex=True)
fig.suptitle("Topics in LDA model", fontsize=40)

for i in range(len(tf_list)):
    tf = tf_vectorizer.fit_transform(tf_list[i])
    n_components = 1
    lda.fit(tf)
    n_top_words = 20
    tf_feature_names = tf_vectorizer.get_feature_names_out()
    top_word_comparison(axes[0], lda, tf_feature_names, n_top_words, sector_list[i])

plt.subplots_adjust(top=0.90, bottom=0.05, wspace=0.90, hspace=0.3)
plt.show()

Getting the error:

IndexError: index 735 is out of bounds for axis 0 with size 1

Which leads me to think that when I changed:

for topic_idx, topic in enumerate(model.components_):
    top_features_ind = topic.argsort()[: -n_top_words - 1 : -1]
    top_features = [feature_names[i] for i in top_features_ind]
    weights = topic[top_features_ind]

to:

for j in range(len(tf_list)):
        top_features_ind = model.components_.argsort()[: -n_top_words - 1 : -1]
        top_features = [feature_names[i] for i in top_features_ind]
        weights = model.components_[top_features_ind]

Conclusion

Even though each fit only has `1` for `components_`, it seems that I can't just replace `topic` with `model.components_` every time it pops up. So, the trouble is:
  • My LDA model just has one component for each run, so we are not plotting one sub plot per component like we might see in the documentation
  • Instead, we are trying to plot sub plots based on entirely new model fits and for that reason, it would make sense to loop over the number of fits/data elements in tf_list. However, when we do so, the matrix algebra seems to collapse


from python - matplot lib sub-plot grid: where to insert row/column arguments

Wednesday, 26 January 2022

Adapt Asp.net JavaScript jsgantt-improved Gantt chart into Blazor

There is one nice looking Gantt chart available with example for Asp.net. However I am having hard times to understand how it can be done in Blazor with razor pages. Can somebody give me some hints how to proceed?

I have placed jsgantt.js and jsgantt.css into wwwroot and also added references in index.html.

But then how to handle that part? Also I guess data should better come from json?

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Gantt.aspx.cs" Inherits="Links2.WebUI.Gannt" %>

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">

    <link href="assets/css/jsgantt.css" rel="stylesheet" type="text/css"/>
    <script src="Scripts/jsgantt.js" type="text/javascript"></script>
    <script src="https://code.jquery.com/jquery-git.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/0.9.0rc1/jspdf.min.js"></script>

    <style>
        .box {
          display: inline-block;
          height: 20px;
          width: 20px;
          border: 2px solid;
        }
        .chartlegend 
        {
            border:1px solid none;
            text-align:right;
            margin-bottom: 30px;            
        }

        .chartlegenditem
        {
            float: right;
            margin-right: 1%;
            filter: alpha(opacity=90);
            opacity: 0.9;
            margin-top: 1px;
        }

        .body-content {
        width: 1800px !important;
    }

    </style>

   
    <%--<input type="button" id="click" value="Export to PDF"/>--%>

    <div class="chartlegend" id="ChartLegendDIV" style="width:1800;"></div>
    <div style="position:relative" class="gantt" id="GanttChartDIV"></div>
    <asp:HiddenField ID="HiddenField" runat="server" />
        <script type="text/javascript">

            var colourList = {
                L1:
                {
                    Title: 'Executing',
                    Colour: '#50C13A'
                },
                L2:
                {
                    Title: 'At Risk',
                    Colour: '#F7E438'
                },
                L3:
                {
                    Title: 'To Do',
                    Colour: '#A9A9A9'
                },
                L4:
                {
                    Title: 'On Hold',
                    Colour: '#2F4F4F'
                },
                L5:
                {
                    Title: 'Planning',
                    Colour: '#3A84C3'
                },
                L6:
                {
                    Title: 'Late',
                    Colour: '#C43A3A'
                },
                L7:
                {
                    Title: 'Initiating',
                    Colour: '#F0F8FF'
                },
                L8:
                {
                    Title: 'Complete',
                    Colour: '#000000'
                }
            };

            colorize = function (colorList)
            {
                    var container = document.getElementById('ChartLegendDIV');
  
                for (var key in colorList) {

                        var details = colorList[key];

                        var boxContainer = document.createElement("DIV");
                        boxContainer.className = 'chartlegenditem';                                               
                        var box = document.createElement("DIV");
                        var label = document.createElement("SPAN");

                        label.innerHTML = details['Title'];
                        box.className = "box";
                        box.style.backgroundColor = details['Colour'];

                        boxContainer.appendChild(box);
                        boxContainer.appendChild(label);

                        container.appendChild(boxContainer);

                   }
            }

            colorize(colourList);

            var g = new JSGantt.GanttChart(document.getElementById('GanttChartDIV'), 'month');

            var list = document.getElementById('<%= HiddenField.ClientID %>').value;

            var result = JSON.parse(list);
               
            vShowRes = document.querySelector('#vShowRes:checked') ? 1 : 0;
            vShowCost = document.querySelector('#vShowCost:checked') ? 1 : 0;
            vShowComp = document.querySelector('#vShowComp:checked') ? 1 : 0;
            vShowDur = document.querySelector('#vShowDur:checked') ? 1 : 0;
            vShowStartDate = document.querySelector('#vShowStartDate:checked') ? 1 : 0;
            vShowEndDate = document.querySelector('#vShowEndDate:checked') ? 1 : 0;
            vShowPlanStartDate = document.querySelector('#vShowPlanStartDate:checked') ? 1 : 0;
            vShowPlanEndDate = document.querySelector('#vShowPlanEndDate:checked') ? 1 : 0;
            vShowTaskInfoLink = document.querySelector('#vShowTaskInfoLink:checked') ? 1 : 0;
            vShowEndWeekDate = document.querySelector('#vShowEndWeekDate:checked') ? 1 : 0;



            g.setOptions({
                vCaptionType: 'Complete',  // Set to Show Caption : None,Caption,Resource,Duration,Complete,     
                vQuarterColWidth: 46, 
                vAdditionalHeaders: { // Add data columns to your table
                        ID:
                        {
                            title: 'ID'
                        },
                        PM:
                        {
                            title: 'PM'
                        },
                        Sponsor:
                        {
                            title: 'Sponsor'
                        }                    
                    },
               
                vDayMajorDateDisplayFormat: 'mon yyyy - Week ww',
            });

            //g.AddTaskItemObject({
            //  pID: 1,
            //  pName: "Define Chart <strong>API</strong>",
            //  pStart: "2017-02-25",
            //  pEnd: "2017-03-17",
            //  pPlanStart: "2017-04-01",
            //  pPlanEnd: "2017-04-15 12:00",
            //  pClass: "ggroupblack",
            //  pLink: "",
            //  pMile: 0,
            //  pRes: "Brian",
            //  pComp: 0,
            //  pGroup: 1,
            //  pParent: 0,
            //  pOpen: 1,
            //  pDepend: "",
            //  pCaption: "",
            //  pCost: 1000,
            //  pNotes: "Some Notes text",
            //  category: "My Category",
            //  sector: "Finance"
            //});

            // or passing parameters

            g.setShowRes(0);
            g.setShowStartDate(0);
            g.setShowEndDate(0);
            g.setShowComp(0);
            g.setShowDur(0);
            g.setScrollTo("today");
            g.setFormatArr('Month', 'Quarter');
            g.setTooltipDelay(200);

            g.AddTaskItem(new JSGantt.TaskItem(1, 'Core', '', '', 'ggroupblack', '', 0, 'Padraic', 0, 1, 0, 1, '', '', '', 'Padraic', g));
            g.AddTaskItem(new JSGantt.TaskItem(2, 'SHP', '', '', 'ggroupblack', '', 0, 'Padraic', 0, 1, 0, 1, '', '', '', 'Padraic', g));
            //g.AddTaskItem(new JSGantt.TaskItem(3, 'Undefined', '', '', 'ggroupblack', '', 0, 'Padraic', 0, 1, 0, 1, '', '', '', 'Padraic', g));
            g.AddTaskItem(new JSGantt.TaskItem(4, 'DES', '', '', 'ggroupblack', '', 0, 'Padraic', 0, 1, 1, 1, '', '', '', 'Padraic', g));
            g.AddTaskItem(new JSGantt.TaskItem(5, 'SES', '', '', 'ggroupblack', '', 0, 'Padraic', 0, 1, 1, 1, '', '', '', 'Padraic', g));
            g.AddTaskItem(new JSGantt.TaskItem(6, 'SDC', '', '', 'ggroupblack', '', 0, 'Padraic', 0, 1, 1, 1, '', '', '', 'Padraic', g));
            g.AddTaskItem(new JSGantt.TaskItem(7, 'PCT', '', '', 'ggroupblack', '', 0, 'Padraic', 0, 1, 1, 1, '', '', '', 'Padraic', g));
            g.AddTaskItem(new JSGantt.TaskItem(8, 'PTA', '', '', 'ggroupblack', '', 0, 'Padraic',   0, 1, 1, 1, '', '', '', 'Padraic', g));


            var IsFirstIteration = true;
            var IsUndefinedTypePresent = false;

            for (var i = 0; i < result.length; i++)
            {
                var statusColour = 'gtaskblack';

                var row = result[i];
                var name = row["Name"];
                var id = row["ID"];
                var start = row["Start"].split('T')[0];
                var finish = row["Finish"].split('T')[0];
                var percentageComplete = row["PercentageComplete"];
                var status = row["Status"];
                var cValue = row["CValue"];
                var pm = row["ProjectManager"];
                var sponsor = row["Sponsor"];
                var valuestream = row["ValueStream"];
                var comments = row["Comments"];

                // Set the parent as undefined by default.
                var parent = 3;

                if (row["SubParent"] != 9) {
                    parent = row["SubParent"];
                }
                else
                {
                    parent = row["Parent"];
                } 

                if (IsFirstIteration)
                {
                    parent = 3;
                    IsFirstIteration = false;
                }

                if (parent == 3 && !IsUndefinedTypePresent)
                {
                    g.AddTaskItem(new JSGantt.TaskItem(3, 'Undefined', '', '', 'ggroupblack', '', 0, 'Padraic', 0, 1, 0, 1, '', '', '', 'Padraic', g));
                    IsUndefinedTypePresent = true;
                }

                //if (percentageComplete == 0)
                //{
                //    percentageComplete = 0.001;
                //}

                switch (cValue) {
                    // Executing
                    case 333:
                        statusColour = 'gtaskgreen';
                        break;
                    // At Risk
                    case 334:
                        statusColour = 'gtaskyellow';
                        break;
                    // Late
                    case 335:
                        statusColour = 'gtaskred';
                        break;
                    // On Hold
                    case 336:
                        statusColour = 'gtaskslategray';
                        break;
                    // Planning
                    case 337:
                        statusColour = 'gtaskblue';
                        break;
                    // To Do
                    case 338:
                        statusColour = 'gtaskgray';
                        break;
                     // Initiating
                    case 350:
                        statusColour = 'gtaskaliceblue';
                        break;
                     // Complete
                    case 351:
                        statusColour = 'gtaskblack';
                        break;
                    default:
                        statusColour = 'gtaskpink';
                        break;
                }
                                
                g.AddTaskItemObject(
                    {                        
                        pID: i + 8,
                        pName: name,
                        pStart: start,
                        pEnd: finish,
                        pLink: '',
                        pClass: statusColour,
                        pMile: 0,
                        pRes: pm,
                        pComp: percentageComplete,
                        pGroup: 0,
                        pParent: parent,
                        pOpen: 1,
                        pNotes: comments,
                        ID: id,
                        PM: pm,
                        Sponsor: sponsor
                }
                );
            }
                        
            g.Draw()

            document.write("<br><br><br><br>");

            //document.getElementById("click").onclick = function ()
            //{
            //    // Default export is a4 paper, portrait, using milimeters for units
            //    var doc = new jsPDF();

            //    //doc.addHTML($('GanttChartDIV')[0], 15, 15, {
            //    //    'background': '#fff',
            //    //});

            //    doc.fromHTML($('GanttChartDIV').html(), 10, 10, {'width' : 340});
            //    doc.save("Test.pdf");

            //    //var doc = new jsPDF();
            //    //doc.addHTML($('#content')[0], 15, 15, {
            //    //    'background': '#fff',
            //    //    }, function() {
            //    //    doc.save('sample-file.pdf');
            //    //});

            //}              

        </script>
        
</asp:Content> 

Repo can be found here: https://github.com/jsGanttImproved/jsgantt-improved



from Adapt Asp.net JavaScript jsgantt-improved Gantt chart into Blazor

Jest throw error when I write test using TypeScript syntax

I have error on my test.ts file,

Module parse failed: Unexpected token

File was processed with these loaders:
./node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js
./node_modules/babel-loader/lib/index.js
You may need an aaadditional loader to handle the result of these loaders.

describe('FormDataAccess`, () => {
  test('Something', () => {
    const formData: FormData = {
      ......
    }
    ......
    expect(ABC).toEquaal(A.B?.C);
})
}

If I remove the :FormData and remove the ? , it will compile successfully.

This is my Jest Config file:

module.exports = {
    preset: 'ts-jest',
    setupFilesAfterEnv: ['./jest.setup.ts'],
    moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
    testPathIgnorePatterns: ['node_modules/', '/src/i18n/__tests__', 'dist/', 'build/'],
    transform: {
        '^.+\\.tsx?$': 'ts-jest',
        '^.+\\.(js|jsx)$': 'babel-jest'
    },
    transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$', '^.+\\.module\\.(css|sass|scss)$'],
    testMatch: ['**/*.(test|spec).(js|ts|tsx)'],
    moduleDirectories: ['node_modules', 'src'],
    moduleNameMapper: {
        '\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': 'identity-obj-proxy',
        '\\.(css|less|scss|sass)$': 'identity-obj-proxy'
    },
    roots: ['<rootDir>', 'src', 'node_modules'],
    modulePaths: ['<rootDir>'],
    clearMocks: true,
    collectCoverage: true,
    collectCoverageFrom: ['src/**/*.{ts,tsx}', '!**/*.stories.{ts,tsx}', '!src/index.ts', '!**/node_modules/**'],
    coverageDirectory: './build/brazil-documentation/coverage',
    coverageReporters: ['json-summary', 'text', 'html', 'cobertura']
};

This is my WebPack config file's rule:

module: {
    rules: [
        {
            // Include ts, tsx, js, and jsx files.
            test: /\.(ts|js)x?$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
                babelrc: true
            }
        },
        {
            test: /\.(png|jpe?g|gif|bmp|svg)$/,
            use: 'url-loader'
        },
        {
            test: /\.css$/i,
            use: ['style-loader', 'css-loader']
        }
    ]
},

Can someone guide me how can I resolve this error, what is a must have in my Jest or webpack config file?

Thanks!



from Jest throw error when I write test using TypeScript syntax