Hauptinhalt

Results for


R2021b is live! There are two new products, five major updates, and hundreds of other feature updates in this latest release. Download or access MATLAB Online to discover what’s new.

New Products

Major Updates

  • Lidar Toolbox - Use Lidar Viewer app to visualize, analyze, and preprocess lidar point clouds interactively
  • Simulink Code Inspector - Use Code Inspector contextual tab to check compatibility, inspect code and view results directly in the model
  • Simulink Control Design - Design Model Reference Adaptive Controllers
  • Symbolic Math Toolbox - Get guidance for symbolic workflows with next-step suggestions in MATLAB Live Editor
  • Wavelet Toolbox - Use wavelet analysis to process and extract features for signals and images for AI workflows

Check out our release highlight page for details.

Share your experience with the community

Are there any new features you find particularly useful? Are you trying the new product to solve a particular problem? Share your story with us no matter it’s big or small. We plan to publish those stories in the highlight channel so that community users can get more out of the new release. A good example is an article written by Adam Danz . If you are interested, contact me via email on my profile card.

Join our celebration of the 20th anniversary of MATLAB Central community! You are invited to enter 2 contests - A Treasure Hunt and a MATLAB Mini Hack - to have fun and win prizes.

How to Play

  • In the Treasure Hunt, complete 10 fun tasks to explore the ‘treasures’ in the community.
  • In the MATLAB Mini Hack, use up to 280 characters of MATLAB code to generate an interesting image. Simply vote for the entries that you like or share your own entries to gain votes.

Prizes

You will have opportunities to win compelling prizes, including special edition T-shirts, customized T-shirts, Amazon gift cards, and virtual badges. Your participation will also bump up our charity donations.

Ready to participate?

Visit the community contests space and choose the contest you’d like to enter. Note that:

  • You need a MathWorks account to participate. If you don’t have a MathWorks account, you can create one at MathWorks sign in .
  • Make sure you follow the contests (click the ‘follow the contests’ button on the top) to get notified for prize information and important announcements.

For the full contest rules, prizes, and terms, see details here .

We hope you enjoy the contests and win big prizes. NOW, LET THE CELEBRATION BEGIN!

Join our celebration of the 20th anniversary of MATLAB Central community! You are invited to enter 2 contests - A Treasure Hunt and a MATLAB Mini Hack - to have fun and win prizes.

How to Play

  • In the Treasure Hunt, complete 10 fun tasks to explore the ‘treasures’ in the community.
  • In the MATLAB Mini Hack, use up to 280 characters of MATLAB code to generate an interesting image. Simply vote for the entries that you like or share your own entries to gain votes.

Prizes

You will have opportunities to win compelling prizes, including special edition T-shirts, customized T-shirts, Amazon gift cards, and virtual badges. Your participation will also bump up our charity donations.

Ready to participate?

Visit the community contests space and choose the contest you’d like to enter. Note that:

  • You need a MathWorks account to participate. If you don’t have a MathWorks account, you can create one at MathWorks sign in .
  • Make sure you follow the contests (click the ‘follow the contests’ button on the top) to get notified for prize information and important announcements.

For the full contest rules, prizes, and terms, see details here .

We hope you enjoy the contests and win big prizes. NOW, LET THE CELEBRATION BEGIN!

Let's say MathWorks decides to create a MATLAB X release, which takes a big one-time breaking change that abandons back-compatibility and creates a more modern MATLAB language, ditching the unfortunate stuff that's around for historical reasons. What would you like to see in it?
I'm thinking stuff like syntax and semantics tweaks, changes to function behavior and interfaces in the standard library and Toolboxes, and so on.
(The "X" is for major version 10, like in "OS X". Matlab is still on version 9.x even though we use "R20xxa" release names now.)
What should you post where?
Wishlist threads (#1 #2 #3 #4 #5): bugs and feature requests for Matlab Answers
Frustation threads (#1 #2): frustrations about usage and capabilities of Matlab itself
Missing feature threads (#1 #2): features that you whish Matlab would have had
Next Gen threads (#1): features that would break compatibility with previous versions, but would be nice to have
@anyone posting a new thread when the last one gets too large (about 50 answers seems a reasonable limit per thread), please update this list in all last threads. (if you don't have editing privileges, just post a comment asking someone to do the edit)
Water
27%
Tea
13%
Coffee
28%
Juice
4%
Something harder
18%
Nothing, I'm good
10%
13353 Stimmen

All the players now have the ability to filter the Cody problems based on the difficulty level. You can also sort based on the difficulty level. Try it out and let us know what you think.

The community team is pleased to release a new design for File Exchange review section. The new design has addressed major pain points we heard from File Exchange users and improves the overall experience. Major improvements include:

1. Support editing ratings/comments

Editing is probably the most popular feature request from File Exchange users. Now, you are able to edit your ratings/comments. Simply click the ‘Edit’ link below your content.

2. Support replying to a comment

In the old design, the only way for the file author to reply to a comment is to create a new comment, which is very hard to track. With the new design, the authors can directly reply to a comment and their post has a blue background making it easier to see. Due to differences between the old and new commenting structures, replies to comments couldn't be reliably inferred, so all comments added prior to 7/14 are at the same indentation level. Replies will be indented from now on.

3. Support rich formatting and attachments

Using the new rich text editor, you are able to choose bold/italic text, insert code or image, create lists, or attach files.

4. Introduce the ‘Discussions’ tab

There is a new ‘Discussions’ tab where community users have conversations with the author or other community members for Q&As or general discussions. The discussions section supports threaded discussions to facilitate the conversations. We separate Discussions with Reviews so that different types of content are not mixed together.

This is a major change for File Exchange and we look forward to hearing from you. Simply reply to this article if you have any questions, comments, or suggestions.

Community members learn about each other or track their own activities via community profile pages. To improve the user experience and address pain points, the community team has redesigned the entire page.

The biggest improvement is we replaced the cards and slider with a dashboard. In this Dashboard, you can easily track your activities by timeline and filter them by different applications (Answers, File Exchange, etc.). All of your stats, such as ranking and reputation, and badges earned are included in one dashboard. If you are looking at your own profile, there are tabs for managing followed content and communication preferences. We also introduced a content feed section, which brings together your contributions alongside your followed content

We encourage you to explore the new profile page. If you have any questions, comments, or suggestions, let us know by leaving a reply to this thread.

New design:

Old design:

Starting in MATLAB R2021a axis tick labels will auto-rotate to avoid overlap when the user manually specifies ticks or tick labels ( release notes ). In custom visualization functions, the tick label density or tick label lengths may be variable and unknown. The new auto-rotation feature removes the burden of detecting the need to rotate manually-set labels and eliminates the need to manually rotate them.

Many properties and combinations of properties can cause tick labels to overlap if they are not rotated.

  • Length of tick labels
  • Number of tick labels
  • Interval between tick labels
  • Font size
  • Font name
  • Figure size
  • Axes size
  • Viewing angle of the axes

Demo: varying tick density and length of tick labels

These 9 axes vary by the number of x-ticks and length of x-tick-labels. MATLAB auto-rotates the labels when needed.

Demo: Changes to axis view angle and rotation

The auto-rotation feature updates the label angles as the axes change programmatically or during user interaction.

What if I don't want auto-rotation?

Auto-rotation mode is on by default for each X|Y|Z axis. When the tick label rotation angle is manually set from the X|Y|ZTickLabelRotation property of axes or by using xtickangle | ytickangle | ztickangle , auto-rotation is turned off. Auto-rotation can also be turned off by setting the X|Y|ZTickLabelRotationMode axis property to manual but it's important to also hold the axis properties so that the rotation mode does not revert to the default value, auto. If you're looking for a broader method of reverting to older behavior you can set the default label rotation mode to manual at the start of a function that produces multiple plots and then revert to the factory default rotation mode at the end of the file (consider using onCleanup).

set(groot,'defaultAxesXTickLabelRotationMode','manual')
set(groot,'defaultAxesYTickLabelRotationMode','manual')
set(groot,'defaultAxesZTickLabelRotationMode','manual')
% Revert to factory-default
set(groot,'defaultAxesXTickLabelRotationMode','remove')
set(groot,'defaultAxesYTickLabelRotationMode','remove')
set(groot,'defaultAxesZTickLabelRotationMode','remove')

A copy of this Community Highlight is attached as a live script.

Four (of many) new features for Apps in MATLAB R2021a

These four new features are the solutions to many inquiries in the Answers forum that continue to receive hundreds of views per month long after they were asked.

Table of Contents

  • Keyboard Shortcuts for UI Components
  • Programmatically scroll UITables
  • Figure always on top
  • UI hyperlink component
  • Demo app: Keyboard shortcut challenge

Keyboard Shortcuts for UI Components

Keyboard shortcuts can now change the focus and make contiguous and non-contiguous selections in ListBox, Table, DatePicker, and ColorPicker menus created in uifigures. The table below summarizes the shortcuts made available in R2021a ( release notes ).

Reminder: in MATLAB R2020b and later you can change the tab order of objects in an app by changing their stack order in AppDesigner using the Reorder tool in the drop-down menu or by right-clicking the component and selecting Reorder from the menu (see R2020b release notes and a screenshot in the Answers forum ).

Programmatically scroll UITables

The scroll function was added in R2016a but as of R2021a it can be used with uitables to programmatically scroll to the top, bottom, left, or right of a table or to a specific row, column or cell ( release notes ). Combined with a uistyle (R2019b) you can scroll to and highlight any part of the uitable.

Syntax examples:

Figure always on top

Figures created with uifigure now have an additional WindowStyle property: 'alwaysontop' ( release notes ). Figures with this setting will stay on top of other windows but unlike the modal option, other windows are still accessible.

See the WindowStyle property description for tips on setting and changing this property.

To toggle the AlwaysOnTop state of your app using a checkbox, state button, or another UI component, follow this callback function template,

function alwaysOnTopCheckBoxValueChanged(app, event)
    value = app.alwaysOnTopCheckBox.Value;
    if value
        app.UIFigure.WindowStyle = 'alwaysontop';
    else
        app.UIFigure.WindowStyle = 'normal';
    end
end

UI hyperlink component

Use the uihyperlink function or the UI hyperlink component in App Designer or a uifigure to add and configure a clickable link ( release notes ). The hyperlink can be assigned to a figure, panel object, tab object, ButtonGroup, or GridLayout object when created in a uifigure. In addition to setting the text and URL, there are lots of properties to control the text format including the VisitedColor property that controls the color of the text after the link is clicked and an optional user-defined HyperlinkClickedFcn function that is evoked when the link is clicked.

Demo app: Keyboard shortcut challenge

The attached zip file contains an app, keyboardShortcutsDemo_R2021a.mlapp , that demonstrates these 4 features. The app displays the extent of arctic sea ice from 1979 to 2016 during the months when extent typically maximizes and minimizes.

Mouseless challenge: After opening the app, without using your mouse, try the following.

  • Select a month (September or March) and any number of years from the list boxes
  • Navigate through the Date Picker and select a date within the range or your selected years (disabled when only 1 year is selected).
  • Navigate to the always-on-top checkbox to pin the app to the top of other windows.
  • Navigate to the text box and enter a year that appears in the uitable to go to that row in the uitable (disabled when only 1 year is selected).
  • Navigate to the URL and press Enter to open the website containing the raw data.

Download the attached zip file, FourNewAppFeatures_R2021a.zip, for a Live script copy of this thread and an app that demonstrates each feature.

Climate Data Toolbox was developed by Chad Greene, a postdoctoral research fellow at NASA Jet Propulsion Laboratory, and Kelly Kearney, a research scientist at University of Washington. The Climate Data Toolbox is freely downloadable from File Exchange and has been downloaded over 5,000 times since 2019.

The toolbox was inspired by one big idea: There are a common set of tasks related to data processing, analysis and visualization that Geoscience researchers and students working with climate data typically perform. Greene and coauthors make the case in their paper published in Geochemistry, Geophysics, Geosystems that having everyone who is tackling climate analysis separately recoding these same tasks is not a good use of time, for the individual or the collective, as it takes away from other more innovative climate work. Better to have a set of reusable, publicly shared functions for those repetitive tasks.

Recently, Lisa Kempler published an example of how to look at the change in temperature of the Pacific Ocean over time using MATLAB and the Climate Data Toolbox.

Try the example here by loading up MATLAB, installing the Climate Data Toolbox, and following along the tutorial.

MATLAB EXPO 2021 is May 4-5, 2021!

MATLAB EXPO is open to everyone:

  • It's free.
  • It's online.
  • Register now. [Edit: Registration is closed]

Industry Tracks:

  • AI in Engineering
  • Modeling and Simulation
  • Implementation, Verification, and DevOps
  • Algorithm Development and Deployment
  • 5G and Radar
  • FPGA, ASIC, and SoC Design
  • Autonomous Systems
  • Teaching with MATLAB and Simulink
  • Cloud and IoT
  • Motor and Power Control

Special Event: Women in Tech Ignite Session

Women in Tech Ignite is a networking event where the MATLAB community can meet and be inspired by a diverse group of women engineers and scientists and hear about the innovative ways they use MathWorks products. Attendees of all genders are welcome.

[Edit: Registration is closed]

We introduced Difficulty Rating functionality during 2020 Cody Contest. Our Cody players have provided difficulty rating for most of the problems. Now we are displaying the ratings in the Problems list view.

Sorting and Filtering to follow...

Introducing content recommendations, a new feed on the community home page with personalized content just for you. MATLAB Central has hundreds of thousands of posts, including files, blogs, questions, and answers. We’re always looking for opportunities to better serve the community as it continues to grow so that visitors can easily help one another and ultimately find what they're looking for.

MATLAB Central has been around for a long time, 20 years this year - more on this milestone in a separate post later. With so much great content it can be a challenge to find what you're looking for or discover new things. We have search and browsing capabilities across the community but even with these robust features you still might not discover some very interesting or relevant content. In the spirit of trying to make sure you don't miss out, we've just released our first version of our recommended content feed. You can see this new feed on the community home page, visible by default via the 'For You' tab.

Recommendations are pulled from across MATLAB Central based on what we think would be relevant to you. We think we have a good starting point and plan on tweaking the algorithms now that it's live. So, expect the feed to only get more relevant over time.

We hope you will find this feature helpful and as always please reply with any feedback you may have.

New in R2021a, LimitsChangedFcn

LimitsChangedFcn is a callback function that responds to changes to axis limits ( release notes ). The function responds to axis interaction such as panning and zooming, programmatically setting the axis limits, or when axis limits are automatically adjusted by other processes.

LimitsChangedFcn is a property of ruler objects which are properties of axes and can be independently set for each axis. For example,

ax = gca(); 
ax.XAxis.LimitsChangedFcn = ... % Responds to changes to XLim
ax.YAxis.LimitsChangedFcn = ... % Responds to changes to YLim
ax.ZAxis.LimitsChangedFcn = ... % Responds to changes to ZLim

Previously, a listener could be assigned to respond to changes to axis limits. Here are some examples.

However, LimitsChangedFcn responds more reliably than a listener that responds to setting/getting axis limits. For example, after zooming or panning the axes in the demo below, the listener does not respond to the Restore View button in the axis toolbar but LimitsChangedFcn does! After restoring the view, try zooming out which does not result in changes to axis limits yet the listener will respond but the LimitsChangedFcn will not. Adding objects to axes after an axis-limit listener is set will not trigger the listener even if the added object expands the axis limits ( why not? ) but LimitsChangedFcn will!

ax = gca(); 
ax.UserData.Listener = addlistener(ax,'XLim','PostSet',@(~,~)disp('Listener')); 
ax.XAxis.LimitsChangedFcn = @(~,~)disp('LimitsChangedFcn')

How to use LimitsChangedFcn

The LimitsChangedFcn works like any other callback. For review,

The first input to the LimitsChangedFcn callback function is the handle to the axis ruler object that was changed.

The second input is a structure that contains the old and new limits. For example,

    LimitsChanged with properties:
      OldLimits: [0 1]
      NewLimits: [0.25 0.75]
         Source: [1×1 NumericRuler]
      EventName: 'LimitsChanged'

Importantly, since LimitsChangedFcn is a property of the axis rulers rather than the axis object, changes to the axes may clear the LimitsChangedFcn property if the axes aren't held using hold on. For example,

% Axes not held
ax = gca(); 
ax.XAxis.LimitsChangedFcn = @(ruler,~)title(ancestor(ruler,'axes'),'LimitsChangedFcn fired!'); 
plot(ax, 1:5, rand(1,5), 'o')
ax.XAxis.LimitsChangedFcn
ans =
    0×0 empty char array
% Axes held
ax = gca(); 
hold(ax,'on')
ax.XAxis.LimitsChangedFcn = @(ruler,~)title(ancestor(ruler,'axes'),'LimitsChangedFcn fired!'); 
plot(ax, 1:5, rand(1,5), 'o')
ax.XAxis.LimitsChangedFcn
ans =
  function_handle with value:
    @(ruler,~)title(ancestor(ruler,'axes'),'LimitsChangedFcn fired!')

Demo

In this simple app a LimitsChangedFcn callback function is assigned to the x and y axes. The function does two things:

  1. Text boxes showing the current axis limits are updated
  2. The prying eyes that are centered on the axes will move to the new axis center

This demo also uses Name=Value syntax and emoji text objects !

Create app

h.fig = uifigure(Name="LimitsChangedFcn Demo", ...
    Resize="off");
h.fig.Position(3:4) = [500,260];
movegui(h.fig)
h.ax = uiaxes(h.fig,...
    Units="pixels", ...
    Position=[200 26 250 208], ...
    Box="on");
grid(h.ax,"on")
title(h.ax,"I'm following you!")
h.eyeballs = text(h.ax, .5, .5, ...
    char([55357 56385 55357 56385]), ...
    HorizontalAlignment="center", ...
    FontSize=40);
h.label = uilabel(h.fig, ...
    Text="Axis limits", ...
    Position=[25 212 160 15], ...
    FontWeight="bold",...
    HorizontalAlignment="center");
h.xtxt = uitextarea(h.fig, ...
    position=[25 191 160 20], ...
    HorizontalAlignment="center", ...
    WordWrap="off", ...
    Editable="off",...
    FontName=get(groot, 'FixedWidthFontName'));
h.ytxt = uitextarea(h.fig, ...
    position=[25 165 160 20], ...
    HorizontalAlignment="center", ...
    WordWrap="off", ...
    Editable="off", ...
    FontName=get(groot, 'FixedWidthFontName'));
h.label = uilabel(h.fig, ...
    Text=['X',newline,newline,'Y'], ...
    Position=[10 170 15 38], ...
    FontWeight="bold");

Set LimitsChangedFcn of x and y axes

h.ax.XAxis.LimitsChangedFcn = @(hObj,data)limitsChangedCallbackFcn(hObj,data,h,'x');
h.ax.YAxis.LimitsChangedFcn = @(hObj,data)limitsChangedCallbackFcn(hObj,data,h,'y');

Update text fields

xlim(h.ax, [-100,100])
ylim(h.ax, [-100,100])

Define LimitsChangedFcn

function limitsChangedCallbackFcn(rulerHand, limChgData, handles, xy)
% limitsChangedCallbackFcn() responds to changes to x or y axis limits.
% - rulerHand: Ruler handle for x or y axis that was changed (not used in this demo)
% - limChgData: LimitsChanged data structure
% - handles: structure of App handles
% - xy: either 'x' or 'y' identifying rulerHand
switch lower(xy)
    case 'x'
        textHandle = handles.xtxt;
        positionIndex = 1; 
    case 'y'
        textHandle = handles.ytxt;
        positionIndex = 2; 
    otherwise
        error('xy is a character ''x'' or ''y''.')
end
% Update text boxes showing rounded axis limits
textHandle.Value = sprintf('[%.3f, %.3f]',limChgData.NewLimits);
% Move the eyes to the new center position
handles.eyeballs.Position(positionIndex) = limChgData.NewLimits(1)+range(limChgData.NewLimits)/2; % for linear scales only!
drawnow
end

See attached mlx file for a copy of this thread.

Highlight Icon image

We are introducing Scratch Pad in Cody to support iterative problem solving. Scratch Pad will enable you to build your solution line-by-line, experiment with different MATLAB functions, and test your solution before submitting.

Try it out and let us know what you think.

Starting in MATLAB R2021a, name-value arguments have a new optional syntax!

A property name can be paired with its value by an equal sign and the property name is not enclosed in quotes.

Compare the comma-separated name,value syntax to the new equal-sign syntax, either of which can be used in >=r2021a:

  • plot(x, y, "b-", "LineWidth", 2)
  • plot(x, y, "b-", LineWidth=2)

It comes with some limitations:

  1. It's recommended to use only one syntax in a function call but if you're feeling rebellious and want to mix the syntaxes, all of the name=value arguments must appear after the comma-separated name,value arguments.
  2. Like the comma-separated name,value arguments, the name=value arguments must appear after positional arguments.
  3. Name=value pairs must be used directly in function calls and cannot be wrapped in cell arrays or additional parentheses.

Some other notes:

  1. The property names are not case-sensitive so color='r' and Color='r' are both supported.
  2. Partial name matches are also supported. plot(1:5, LineW=4)

The new syntax is helpful in distinguishing property names from property values in long lists of name-value arguments within the same line.

For example, compare the following 2 lines:

h = uicontrol(hfig, "Style", "checkbox", "String", "Long", "Units", "Normalize", "Tag", "chkBox1")
h = uicontrol(hfig,  Style="checkbox",    String="Long",    Units="Normalize",    Tag="chkBox1")

Here's another side-by-side comparison of the two syntaxes. See the attached mlx file for the full code and all content of this Community Highlight.

tiledlayout, introduced in MATLAB R2019b, offers a flexible way to add subplots, or tiles, to a figure.

Reviewing two changes to tiledlayout in MATLAB R2021a

  1. The new TileIndexing property
  2. Changes to TileSpacing and Padding properties

1) TileIndexing

By default, axes within a tiled layout are created from left to right, top to bottom, but sometimes it's better to organize plots column-wise from top to bottom and then left to right. Starting in r2021a, the TileIndexing property of tiledlayout specifies the direction of flow when adding new tiles.

tiledlayout(__,'TileIndexing','rowmajor') creates tiles by row (default).

tiledlayout(__,'TileIndexing','columnmajor') creates tiles by column.

.

2) TileSpacing & Padding changes

Some changes have been made to the spacing properties of tiles created by tiledlayout.

TileSpacing: sets the spacing between tiles.

  • "loose" is the new default and replaces "normal" which is no longer recommended but is still accepted.
  • "tight" replaces "none" and brings the tiles closer together still leaving space for axis ticks and labels.
  • "none" results in tile borders touching, following the true meaning of none.
  • "compact" is unchanged and has slightly more space between tiles than "tight".

Padding: sets the spacing of the figure margins.

  • "loose" is the new default and replaces "normal" which is no longer recommended but is still accepted.
  • "tight" replaces "none" and reduces the figure margins. "none" is no longer recommended but is still accepted.
  • "compact" is unchanged and adds slightly more marginal space than "tight".
  • Reducing the figure margins to a true none is still not an option.

The release notes show a comparison of these properties between r2020b and r2021a.

Here's what the new TileSpacing options (left column of figures below) and Padding options (right column) look like in R2021a. Spacing properties are written in the figure names.

.

And here's a grid of all 12 combinations of the 4 TileSpacing options and 3 Padding options in R2021a.

.

Code used to generate these figures

%% Animate the RowMajor and ColumnMajor indexing with colored tiles 
fig1 = figure('position',[200 200 560 420]); 
tlo1 = tiledlayout(fig1, 3, 3, 'TileIndexing','rowmajor');
title(tlo1, 'RowMajor indexing')
fig2 = figure('position',[760 200 560 420]); 
tlo2 = tiledlayout(fig2, 3, 3, 'TileIndexing','columnmajor');
title(tlo2, 'ColumnMajor indexing')
colors = jet(9);
drawnow()
for i = 1:9
    ax = nexttile(tlo1);
    ax.Color = colors(i,:);
    text(ax, .5, .5, num2str(i), 'Horiz','Cent','Vert','Mid','Fontsize',24)
      ax = nexttile(tlo2);
      ax.Color = colors(i,:);
      text(ax, .5, .5, num2str(i), 'Horiz','Cent','Vert','Mid','Fontsize',24)
      drawnow
      pause(.3)
  end
%% Show TileSpacing options
tileSpacing = ["loose","compact","tight","none"];
figHeight = 140;  % unit: pixels
figPosY = fliplr(50 : figHeight+32 : (figHeight+30)*numel(tileSpacing)); 
for i = 1:numel(tileSpacing)
    uif = uifigure('Units','Pixels','Position', [150 figPosY(i) 580 figHeight], ...
        'Name', ['TileSpacing: ', tileSpacing{i}]);
    tlo = tiledlayout(uif,1,3,'TileSpacing',tileSpacing(i)); 
    h = arrayfun(@(i)nexttile(tlo), 1:tlo.GridSize(2));
    box(h,'on')
    drawnow()
end
%% Show Padding options
padding = ["loose","compact","tight"];
for i = 1:numel(padding)
    uif = uifigure('Units','Pixels','Position', [732 figPosY(i) 580 figHeight], ...
        'Name', ['Padding: ', padding{i}]);
    tlo = tiledlayout(uif,1,3,'Padding',padding(i)); 
    h = arrayfun(@(i)nexttile(tlo), 1:tlo.GridSize(2));
    box(h,'on')
    drawnow()
end
%% Show all combinations of TileSpacing and Padding options
tileSpacing = ["loose","compact","tight","none"];
padding = ["loose","compact","tight"];
[tsIdx, padIdx] = meshgrid(1:numel(tileSpacing), 1:numel(padding));
figSize = [320 220]; % width, height (pixels)
figPosX = 150 + (figSize(1)+2)*(0:numel(tileSpacing)-1); 
figPosY = 50 + (figSize(2)+32)*(0:numel(padding)-1);
[figX, figY] = meshgrid(figPosX, fliplr(figPosY));
for i = 1:numel(padIdx)
    uif = uifigure('Units','pixels','Position',[figX(i), figY(i), figSize], ...
        'name', ['TS: ', tileSpacing{tsIdx(i)}, ', Pad: ', padding{padIdx(i)}]);
    tlo = tiledlayout(uif,2,2,'TileSpacing',tileSpacing(tsIdx(i)),'Padding',padding(padIdx(i))); 
    h = arrayfun(@(i)nexttile(tlo), 1:prod(tlo.GridSize));
    box(h,'on')
    drawnow()
end

Did you know you can use most emoticons in text objects?

Most emoticons are just unicode characters. Using them as characters in Matlab is as simple as finding their numeric representation and then converting the numeric value back to character. Not all emoticons are convertible in Matlab.

Here's a secret message with emoticons. Use char(x) to decode it.

x = [79 77 71 33 32 55357 56878 32 104 97 118 101 32 121 111 ...
    117 32 117 112 100 97 116 101 100 32 116 111 32 77 97 116 ...
    108 97 98 32 55358 56595 32 114 50 48 50 49 97 32 121 101 116 32 8265];

Happy St. Patrick's Day!

fig = figure('MenuBar','none','Color', [0 .62 .376]);  % Shamrock green
ax = axes(fig,'Units','Normalized','Position',[0 0 1 1]);
axis(ax,'off')
axis(ax,'equal')
hold(ax,'on')
xlim(ax,[-1,1]); ylim(ax,[-1,1])
text(ax, 0, 0, char(9752), 'VerticalAlignment','middle','HorizontalAlignment','center','FontSize', 200)
str = num2cell('Happy St Patrick''s day!');
th = linspace(-pi/2,pi/2,numel(str)); 
txtHandle = text(ax,sin(th)*.8, cos(th)*.8, str, 'VerticalAlignment','middle','HorizontalAlignment','center','FontSize', 25);
set(txtHandle,{'rotation'}, num2cell(rad2deg(-th')))
thr = 0.017;
rotateCCW = @(xyz)([cos(thr) -sin(thr) 0; sin(thr), cos(thr), 0; 0 0 1]*xyz.').';
while all(isvalid(txtHandle))
    newposition = rotateCCW(vertcat(txtHandle.Position)); 
    set(txtHandle,{'position'}, mat2cell(newposition,ones(numel(txtHandle),1),3), ...
        {'rotation'}, num2cell([txtHandle.Rotation].'+thr*180/pi))
    drawnow()
end

We've all been there. You've got some kind of output that displays perfectly in the command window and you just want to capture that display as a string so you can use it again somewhere else. Maybe it's a multidimensional array, a table, a structure, or a fit object that perfectly displays the information you need in a neat and tidy format but when you try to recreate the display in a string variable it's like reconstructing the Taj Mahal out of legos.

Enter Matlab r2021a > formattedDisplayText()

Use str=formattedDisplayText(var) the same way you use disp(var) except instead of displaying the output, it's stored as a string as it would appear in the command window.

Additional name-value pairs allow you to

  • Specify a numeric format
  • Specify loose|compact line spacing
  • Display true|false instead of 1|0 for logical values
  • Include or suppress markup formatting that may appear in the display such as the bold headers in tables.

Demo: Record the input table and results of a polynomial curve fit

load census
[fitobj, gof] = fit(cdate, pop, 'poly3', 'normalize', 'on')

Results printed to the command window:

fitobj = 
     Linear model Poly3:
     fitobj(x) = p1*x^3 + p2*x^2 + p3*x + p4
       where x is normalized by mean 1890 and std 62.05
     Coefficients (with 95% confidence bounds):
       p1 =       0.921  (-0.9743, 2.816)
       p2 =       25.18  (23.57, 26.79)
       p3 =       73.86  (70.33, 77.39)
       p4 =       61.74  (59.69, 63.8)
gof = 
  struct with fields:
             sse: 149.77
         rsquare: 0.99879
             dfe: 17
      adjrsquare: 0.99857
            rmse: 2.9682

Capture the input table, the printed fit object, and goodness-of-fit structure as strings:

rawDataStr = formattedDisplayText(table(cdate,pop),'SuppressMarkup',true)
fitStr = formattedDisplayText(fitobj)
gofStr = formattedDisplayText(gof)

Display the strings:

rawDataStr = 
    "    cdate     pop 
         _____    _____
         1790       3.9
         1800       5.3
         1810       7.2
         1820       9.6
         1830      12.9
         1840      17.1
         1850      23.1
         1860      31.4
         1870      38.6
         1880      50.2
         1890      62.9
         1900        76
         1910        92
         1920     105.7
         1930     122.8
         1940     131.7
         1950     150.7
         1960       179
         1970       205
         1980     226.5
         1990     248.7
     "
fitStr = 
    "     Linear model Poly3:
          ary(x) = p1*x^3 + p2*x^2 + p3*x + p4
            where x is normalized by mean 1890 and std 62.05
          Coefficients (with 95% confidence bounds):
            p1 =       0.921  (-0.9743, 2.816)
            p2 =       25.18  (23.57, 26.79)
            p3 =       73.86  (70.33, 77.39)
            p4 =       61.74  (59.69, 63.8)
     "
gofStr = 
    "           sse: 149.77
            rsquare: 0.99879
                dfe: 17
         adjrsquare: 0.99857
               rmse: 2.9682
     "

Combine the strings into a single string and write it to a text file in your temp directory:

txt =  strjoin([rawDataStr; fitStr; gofStr],[newline newline]);
file = fullfile(tempdir,'results.txt');
fid = fopen(file,'w+');
cleanup = onCleanup(@()fclose(fid)); 
fprintf(fid, '%s', txt);
clear cleanup

Open results.txt.

winopen(file) % for Windows platforms