File Exchange Pick of the Week

Our best user submissions

20th Anniversary – Most Active FEX Entries

Jiro's picks this week are the following 4 entries:
This year was 20th anniversary of MATLAB Central, and to celebrate we held a couple of contests, the Treasure Hunt and the Mini Hack. 5 years ago, I wrote this post to highlight the most active/interactive File Exchange entry, as part of the 15th anniversary. In this post, let's look at some of the most active and interactive File Exchange entries in the last 5 years.

Entries with most comments

Just like last time, let's first look at the entries with the most number of comments posted in the last 5 years (Jan 2017 to Dec 2021).
load FEX2017to2021.mat addonsAfter2016 commentsAfter2016 versionsAfter2016
addonsAfter2016 = sortrows(addonsAfter2016,"NumComments","descend");
bar([addonsAfter2016.NumAuthorComments(1:10), addonsAfter2016.NumUserComments(1:10)],"stacked")
title("Number of comments (since Jan 2017)")
legend("Author Comments", "User Comments", "Location", "northeast")
If we look at the total number of comments, we see that the top entry is MATLAB File Association & Shortcut Fix by Patrik Forssén. In fact, this file was selected as a Pick of the Week back in 2016.

Wordcloud on comments

We see that some entries have comments mostly from users, while others have more comments from the author of the entries, suggesting a "conversation" between the users and the author. Of course, entries with comments mostly from users are no less valuable. Doing a quick word cloud on the comments on "MATLAB File Association & Shortcut Fix" seems to show a lot of praise for the entry.
addonsAfter2016 = sortrows(addonsAfter2016,"NumComments","descend");
% Extract all comments from "MATLAB File Association & Shortcut Fix"
textData = commentsAfter2016.Comment(commentsAfter2016.AddOnUUID == addonsAfter2016.AddOnUUID(1) & ~commentsAfter2016.IsCommentByContributor);
title("Comments: " + addonsAfter2016.Name(1))

Entries with most author comments

Let's see which entries had many comments from authors.
addonsAfter2016 = sortrows(addonsAfter2016,"NumAuthorComments","descend");
bar([addonsAfter2016.NumAuthorComments(1:10), addonsAfter2016.NumUserComments(1:10)],"stacked")
title("Number of comments (since Jan 2017)")
legend("Author Comments", "User Comments", "Location", "northeast")
Very nice! These entries seem to have a nice balance between author and user comments.

Most updated entries

How about number of updates? Entries that are frequently updated indicate that they are actively maintained by the author.
addonsAfter2016 = sortrows(addonsAfter2016,"NumUpdates","descend");
title("Number of updates (since Jan 2017)")

Looking at a few metrics

We already see a few entries that show up in multiple bar charts. Let's try to visualize a few of these metrics together and see which ones stand out.
First, I'll arbitrarily choose entries that have at least 100 comments since Jan 2017.
addonsAfter2016_over100comments = addonsAfter2016(addonsAfter2016.NumComments > 100,:);
numEntries = height(addonsAfter2016_over100comments)
numEntries = 47
47 entries. That's a good number to work with.
Let's calculate the ratio of author comments to all comments and sort based on the ratio. I do this, since I wanted to see which entries had a relatively large number of author comments compared to overall comments.
addonsAfter2016_over100comments.AuthorCommentRatio = addonsAfter2016_over100comments.NumAuthorComments ./ addonsAfter2016_over100comments.NumComments;
addonsAfter2016_over100comments = sortrows(addonsAfter2016_over100comments,"AuthorCommentRatio","descend");
We will now look at the following 3 metrics:
  1. Number of author comments
  2. Ratio of author comments to overall comments
  3. Number of updates
I will rank the 47 entries based on these metrics and look at a heatmap.
[~, id_author_comments] = sort(addonsAfter2016_over100comments.NumAuthorComments,"descend");
[~, id_author_ratio] = sort(addonsAfter2016_over100comments.AuthorCommentRatio,"descend");
[~, id_updates] = sort(addonsAfter2016_over100comments.NumUpdates,"descend");
rankings(id_author_comments,1) = 1:numEntries;
rankings(id_author_ratio,2) = 1:numEntries;
rankings(id_updates,3) = 1:numEntries;
heatmap(rankings,"XDisplayLabels",["Num Author Comments","Author Comment Ratio","Num Updates"],...
"YDisplayLabels", addonsAfter2016_over100comments.NameShort)
Here are the entries that ranked in under 10 in all three categories.
selectedEntries = addonsAfter2016_over100comments(rankings(:,1) < 10 & rankings(:,2) < 10 & rankings(:,3) < 10,:);
selectedEntries(:,["Name" "ID" "Author" "NumComments" "NumAuthorComments" "AuthorCommentRatio" "NumUpdates"])
ans = 4×7 table
1"Systemic Risk"62482Tommaso Belluzzo158610.386188
2"fitVirusCOVID19"74658milan batista210780.371456
4"xiangruili/dicm2nii"42997Xiangrui Li150550.366719

Visualize interactions

Let's look at the timings of the interactions in these entries. You'll notice that these interactions happen consistently, which is great to see.
Systemic Risk
This entry has had the highest number of updates in this time frame, which have most likely been motivated by the many comments from the users.
As you might expects, this one came out soon after the pandemic outbreak. You see a lot of discussions happening the first half of 2020.
This entry has been selected as a pick of the week a couple of times in the past. The first Pick was on Oct 2019, and you can see that Moses started to increase his update frequency around that time.
The file updates for this entry have stopped, but Xiangrui continues to communicate with his users through the comments.


Congratulations to these 4 entries. MATLAB Central and File Exchange exist because of the community contributions. We appreciate the discussions you have to improve the quality of the content on this site! Please tell us what you think here or leave a comment to the authors.

Helper function for creating timeline plot

function createTimelinePlot(id,selectedEntries,commentsAfter2016,versionsAfter2016)
commentsForEntry = commentsAfter2016(commentsAfter2016.AddOnUUID == selectedEntries.AddOnUUID(id),:);
x = commentsForEntry.Date;
y = 2*ones(height(commentsForEntry),1);
y(commentsForEntry.IsCommentByContributor) = 3;
versionsForEntry = versionsAfter2016(versionsAfter2016.AddOnUUID == selectedEntries.AddOnUUID(id),:);
ylim([0 3.5])
hold on
plot([versionsForEntry.Date, versionsForEntry.Date]',...
hold off
yticks([0.5 2 3])
yticklabels(["Updates", "User Comments", "Author Comments"])
title([selectedEntries.Name(id) selectedEntries.Author(id)],"Interpreter","none")
  • print


To leave a comment, please click here to sign in to your MathWorks Account or create a new one.