## Loren on the Art of MATLABTurn ideas into MATLAB

### This is machine translation

Translated by
Mouseover text to see original. Click the button below to return to the English version of the page.

# MATLAB R2014b Graphics – Part 1: Features of the New Graphics System43

Posted by Loren Shure,

Today I’d like to introduce a guest blogger, David Garrison, who is a MATLAB Product Manager here at MathWorks. This is the first in a series of blogs over the next few weeks describing the new graphics system in R2014b and how some of the changes will affect you.

• Part 1: Features of the New Graphics System
• Part 2: Using Graphics Objects
• Part 3: Compatibility Considerations in the New Graphics System

Here is Part 1 of the series.

### Contents

#### Big Changes in R2014b

There are a number of big changes in R2014b. Some of the new features include:

• New MATLAB graphics system
• Date and time data types with time zone and display options
• Git and Subversion source control integration and access to projects on GitHub from File Exchange
• MATLAB MapReduce™ data analysis that scales Hadoop for big data
• Arduino and Android hardware support for interacting with motors and actuators, and for accessing sensor data

You can learn more about all these features in the MATLAB R2014b Release Notes. This post is all about the new graphics system.

#### The New MATLAB Graphics System

R2014b includes a new MATLAB graphics system. The new graphics system includes many new features which we will describe in this blog post. In Part 2 of this series, we will describe how graphics handles have changed in R2014b and how to use graphics objects. Finally, there are some changes in the new system which may require changes in some existing graphics related code. We'll discuss compatibility considerations in Part 3 of this series.

#### The New Look of MATLAB Graphics

When you create a plot in R2014b, you'll see that MATLAB graphics look different than previous versions.

The first thing that you will notice is that lines are plotted using a different set of colors. New line colors were selected to make it easier to distinguish lines from one another and to help people with certain types of color blindness. There is also a new default colormap in R2014b called parula. The colors in the parula colormap are ordered from dark to light and are perceptually uniform. Smooth changes in the data appear as smooth changes in color, while sharp changes in the data appear as sharp changes in color. Grid lines are now gray to make data stand out visually. Axis labels and titles are larger and more prominent. Lines and text are now anti-aliased (smoothed) to remove jagged edges.

#### Rotatable Tick Labels

If you're like me, you sometimes need to use long labels for the ticks in your plot. In previous versions of MATLAB, tick labels were always displayed horizontally as shown on the left in the example below. In the new graphics system, ticks can be rotated so you can create a plot like that shown on the right. Tick labels on both the x and y axes can be rotated.

For example, to rotate the X tick labels, use the XTickLabelRotation property of the Axes object:

ax = gca;
ax.XTickLabelRotation = -40;


#### Automated Updating of datetime Tick Labels

R2014b includes a new date and time data type called a datetime array. When you create a plot with a datetime array, the tick labels will automatically update as you pan or zoom in the plot. Tick labels change from days to hours to minutes to seconds as shown below.

#### Animated Plots

MATLAB R2014b graphics introduces a new function called animatedline. The code below shows how to create an animatedline and add points to it.

x = 1:100;
y = rand(1,100);
myLine = animatedline;
myLine.Color = blue;
xlim([1 100])
ylim([0 1])
for i = 1:100
pause(0.1)
end


The result is a plot that changes over time. The picture below shows how the plot looks at iterations 20, 50, and 80 as points are added.

#### Multilingual Text and Symbols in Plots

R2014b graphics also supports the use of Unicode characters to show multilingual text in axis labels and titles and in user interface controls. Here is an example. See the native2unicode function for more information about Unicode strings.

#### User Interfaces with Tab Panels

Creating a user interface with tab panels has been a common request among MATLAB UI builders. In the past, people had done it using undocumented functions. In R2014b, those functions have been updated and are now fully documented and supported.

You can easily create a user interface like the one shown above using the new uitabgroup and uitab functions.

myFig = figure('Toolbar', 'none', ...                     % Create the figure
'Menubar', 'none', 'Name', 'Using Tab Panels');
tgroup = uitabgroup('Parent', myFig);                     % Create the tabgroup
tab1 = uitab('Parent', tgroup, 'Title', 'Loan Data');     % Create the tabs
tab2 = uitab('Parent', tgroup, 'Title', 'Amortization Table');
tab3 = uitab('Parent', tgroup, 'Title', 'Principal/Interest Plot');


#### Improved Histograms

The new histogram function plots histograms with data-dependent bin picking. It provides capabilities that the traditional hist function does not including options for bin control, normalization, and visualization.

The code below shows how to create two overlapping histograms and modify their properties after they are created.

data1 = randn(5000,1);
data2 = randn(5000,1)+ 2;

h1 = histogram(data1);
hold on
h2 = histogram(data2);
hold off
legend show

h1.BinMethod = 'sturges';
h2.Normalization = 'countdensity';


#### Have you tried the new graphics system in R2014b?

Have you installed MATLAB R2014b? Have you tried the new graphics system? We'd love to hear your thoughts here.

#### Next up -- Part 2: Using Graphics Objects

Well, that's all for now. Be sure to check out Mike Garrity's new blog, Mike on MATLAB Graphics, for some cool ideas about what you can do with the new graphics system.

In my next post I'll talk about how graphics handles have changed in R2014b and how to use graphics objects.

Get the MATLAB code

Published with MATLAB® R2014b

### Note

Rob replied on : 1 of 43
The datetime feature to allow zooming of plots is welcome - with the advantage that you don't need to do a datetick('x') type command to get human readable xlabel values. However... how do you set the format of those time strings? I see I can still use datetick('x','HH:MM') type commands to set the date/time format - but from then on it removes the ability to zoom in and have new appropriate time tick marks. I presume the datetime function does not allow milliseconds? (Datestr does.) I think this datetime value is a welcome addition. However I'd really like it to have millisecond or greater accuracy as an option too. I presume Matlab still has no date/time functions that can cope with leap seconds? Also I presume there's still no easy way to work out day of year within the format commands? To find the day-of-year number of 2014-10-03 I generally do something like this: t = datenum(2014,10,3,16,04,20); doy = floor(t)-datenum(str2double(datestr(t,'yyyy'))-1,12,31); i.e. floor in case time is not midnight, and minus the last day of the year before. Is there a more Matlab-y way of doing this? Back to plotting - is there a way to have several lines of XTickLabels with the new graphics? For instance I may want a simply 2D plot and on my X-Axis labels I may want time (human readable), but also a second row of value to represent distance, then a third row of xticklabels to represent velocity, etc. Basically each XTickLabel is now a string of multiple rows that are each centered appropriately. Is there an easy command for this? Finally the new graphics routine did break my old codes. Previously when drawing a colorbar for data on a log scale I'd do something like imagesc(log10(data)) ; data has values of 1 to 1000 h = colorbar; then my colorbar has a range 0-3 that really represent 1, 10, 100, 1000 I could then do axes(h) then replace YTickLabels with [] and use text commands to write in strings of '10^1' etc to get 10 superscript 1 at the appropriate place on the colorbar. However in 2014b, axes(h) (when h=colorbar) gives an error. That's easily fixed with the wonderful new code: colorbar('Ticks',[0,1,2,3],'TickLabels',{'10^{0}','10^{1}','10^{2}','10^{3}'}) But that code does not work on Matlab 2014a or earlier. This has resulted in me having to alter my codes (shard with others) to check the Matlab version (a = version('-release');) and use the appropriate code to correctly label my linear colorbar as a log colorbar. Would be nice if colorbars could more easily cope with log spaced data. New graphics routine look like an improvement... but I wonder if it does all the items I'd hope for above. If so, wonderful, could you provide some example code?
Jotaf replied on : 2 of 43
Wow this is great! I was wondering when the final wrinkles of HG2 would be ironed out and it would become officially supported in Matlab. This is a major overhaul of the way plots look by default, and I'm sure we will start seeing prettier plots in publications as a result! ;) Looking forward to the next articles in this series.
Giorgio replied on : 3 of 43
Maybe there is some setting I have not found yet but R2014b plots look worse than R2014a on OS X 10.9.5. The lines are jagged while before they were not. The pdf outputs are jagged too. This seems to be in accordance with the new matlab documentation where they say that version 3.0 or later of OpenGL must be used. On the contrary, "opengl info" detects version 2.1, that seems to be the compatibility mode version.
Sarah Zaranek replied on : 4 of 43
Hi Rob - I can answer some of your questions regarding datetime. When you plot datetime ticks, you can add an optional string to specify the format of the dates. There is a year property of datetime. So, you can get the year easily that way, such as d.Year. If you want to do more involved shifting of the date, you can use dateshift to do that. Datetime has nanosecond precious and accounts for daylight saving time and leap seconds. You can set the TimeZone property to account for leap seconds. I would encourage you to look at the datetime documentation. Or watch this introductory video: https://www.mathworks.com/videos/date-and-time-arrays-95317.html?type=shadow Cheers, Sarah
thom replied on : 5 of 43
Hello Loren, i have a suggestion for editor, can i share it with you? :) Regarding to bracket highlighting... now its done with underlining the bracket pair. Its pretty confusing and visually not convenient. My suggestion is to highlight the bracket pairs (all of them) with different colours... Or even better, each color corresponds to a different bracket level. Example: 3*{A*[B+3]*D+3*[D+(A+2)*(B+1)*(C+2)]} Here, each type of bracket stands for a differently coloured highlighted bracket. I hope its clear :)
Steve Eddins replied on : 6 of 43

Why do you presume that datetime does not allow milliseconds? Datetime has very high precision, up to nanosecond precision (over something like 100 days). For converting string formats that contain fractional seconds, see the documentation for the Format property of datetime objects. Use S, SS, SSS, ..., for reading in date strings that contain fractions of a second, up to 9 fractional digits.

In the same portion of the documentation, you'll see that D, DD, and DDD are used to format dates using day-of-year.

In the documentation for the TimeZone property, you'll see that you can specify 'UTCLeapSeconds' to create a datetime array in Universal Coordinated Time that accounts for leap seconds.

Stephan replied on : 7 of 43
I have two big issues with the old graphics system:

1. plots with more than one y-axis: plotyy is very limited and doing it by hand is very complicated

2. saving images to files: Saving as emf gives you almost the same as you see on the screen but it does not support all features (transparency, RGB colors...). All the other formats change the whole layout (font sizes, x/y-ticks, legend position, ...) and it is always try and error until you have a good looking image. Multipage-PDF is not supported either.

Are there any improvement in those areas?

Peter Perkins replied on : 8 of 43
Rob, I hope you will be happy to hear that all of your presumptions about date/time plotting are incorrect. The doc talks about all of this. I think Loren may also talk more about the new data types for dates and times in a future post. 1) When you plot a datetime or duration array, you can use the DatetimeTickFormat or DurationTickFormat name/value pair to specify a specific format for the tick labels. But be aware that using those means that as you zoom or pan, the format will not adjust to show more or less information as necessary. Unless you want to make a static plot, best to let plot do its thing. Don't mix the new functionality with the old datetick function. Also be aware that the format strings for datetime are somewhat different than those for the old datestr/datenum functions, and in particular are case-sensitive. As a result, there is quite a lot of new display functionality available. 2) datetime display and calculations support not just milliseconds, but all the way down to nanoseconds. Include something like ss.SSS or ss.SSSSSSSSS in your format. If you zoom a datetime plot are enough, you should see milliseconds in the tick labels. 3) Use the UTCLeapSeconds "time zone" for leap second support. Leap seconds are not supported in other "civil" time zones such as America/New_York, which include support for daylight saving time (where appropriate). The choice of display format for UTCLeapSeconds is currently limited to one of the ISO8601 formats. 4) The format identifier for day of year is D (case sensitive).
Sean de Wolski replied on : 9 of 43
Rob, one more function to help with branching based on release is "verLessThan" if verLessThan('matlab',8.4) % Before 14b else % 14b or newer end
David Garrison replied on : 10 of 43
Rob, Regarding your question about Tick Labels on colorbar. Here's the situation: Prior to R2014b, colorbar and legend were axes objects. Also TeX interpretation did not work for tick labels. I assume that is why you were using text objects to get tick labels with real exponents. In R2014b, colorbar and legend have their own special objects. In R2014b, TeX interpretation can now be used in tick labels (as you discovered). Your best bet for now is to branch your code using verLessThan as Sean suggested. I will add an enhancement request to have colorbars handle log scaling.
Rob replied on : 11 of 43
David Garrison replied on : 12 of 43
Stephan, Regard your comment on plotyy. There are no changes to plotyy in this release. However, now that the new graphics system is out, we will start working on improvements to existing capabilities like plotyy. Regarding your comment on saving to emf, there have been some improvements there: 1) The new graphics system does provide some additional support for transparency. It supports "background" transparency if you set your figure or axes color to 'none'. It has more support for transparency in the figure contents; setting FaceAlpha to .5 on a surface will be honored when generating the EMF file. 2) The default renderer in the new graphics system is OpenGL. Transparency will not work in a saved file if the renderer is set to OpenGL. You should change the renderer to 'Painters' before you save or print. 3) In general, the output can be made to look more like the screen by setting 2 figure properties: set(fig, 'PaperPositionMode', 'auto') and set(fig, 'InvertHardcopy', 'off'). PaperPositionMode 'auto' tells us to generate the output at the same size as the onscreen figure, which should avoid many of the layout-related changes. 4) We still do not support multi-page PDF directly in MATLAB but you can create multi-page Postscript files then convert them to PDF using an external tool.
Sarah Zaranek replied on : 13 of 43
Hi Rob - For plotting datetimes, I meant in the plotting function. Sorry not to be more specific about the name-value pair. You can read more about this in the documentation for plot. The video is actually mine - and I will take your comment and see if I can make it clearer. For calculating day of year, Peter might have something more elegant. But between might be the best way to do it, for example -- between(datetime('1-Jan-2012'),t2,'days') This returns a calendarDuration which you can then make a double if you wish. caldays(between(datetime('1-Jan-2012'),t2,'days')) Peter can speak more to the choice of formats and rounding. Cheers, Sarah
Dan Seal replied on : 14 of 43
Hi Rob, Day of year can be extracted directly with the the new "day" function: doy = day(t,'dayofyear'); https://www.mathworks.com/help/matlab/ref/day.html
Peter Perkins replied on : 15 of 43
Rob, the things you are seeing with fractional seconds are due to a combination of display behavior, and round-off in the numbers you are using to create your datetimes. Details follow below, but in short, you are not passing into datetime what you think you are. There are ways to solve that. This is getting a bit far afield from the original blog post topic, but anyway I hope this will help you get more comfortable with the new datetime data type. First, one high-level comment: it's fine to compare the behavior and results from the new datetime data type to those from datenum and datestr, but you'll be happiest if you don't try to mix the two together. So for example, don't use datetick when plotting datetimes, and don't create datenums only to turn them into datetimes. You _can_, but things will be less confusing if you go all in. Now on to answering your questions one by one: * Yes, the format strings for datetime differ somewhat from those for datestr. datetime uses the standard defined by the Unicode Common Locale Data Repository, which supports a slew of things the datestr formats do not, day of year among them. You will have to overcome some muscle memory where things are different, but I think you will find the change to be worth it in the long run. * To get the day(s) of year from a datetime array as a number, use the day function. To display it, use D in the format: >> dt = datetime dt = 07-Oct-2014 09:08:15 >> day(dt,'dayofyear') ans = 280 >> dt.Format = 'yyyy-D HH:mm:ss' dt = 2014-280 09:08:15 You can also get the number of days since the beginning of the year as a calendar duration, using between as Sarah suggests, or even as a duration, using subtraction, but I don't think that's what you wanted. * Rounding vs. truncation in display: I think everyone would be unhappy if 10:59:59, displayed using HH:mm, was rounded up to display as 11:00. The same philosophy applies to fractional seconds in datetime. Round-to-nearest is how numbers display in MATLAB, but that's not how most people want time to work. So if you have 56.020995361 seconds, and display it using ss.SSS, you see 56.020, not 56.021. * Combined with the display behavior described above, you are seeing some problems due to round-off in the numbers you are passing into datetime. Consider 56.000000001. In double precision, it is really more like this: >> format long >> 56.000000001 ans = 56.000000000999997 So the number you've passed into datetime is less than 56.000000001, and because of the way datetime displays, you see 56.000000000. But the number of seconds you passed in is really in there, and you can demonstrate that with a slightly modified version of your example: >> dt = datetime(2014, 10, 06, 12, 04, [0,56.000000001]) dt = 06-Oct-2014 12:04:00 06-Oct-2014 12:04:56 >> dt.Format = 'dd-MMM-yyyy HH:mm:ss.SSSSSSSSS' dt = 06-Oct-2014 12:04:00.000000000 06-Oct-2014 12:04:56.000000000 Now get the difference of those two datetimes as a duration, and convert that to a double precision number of seconds: >> seconds(diff(dt)) ans = 56.000000000999997 * So how to get what you actually want? You already found that using strings preserves the precision. But how to do it with numbers? Here's one way: >> dt = datetime(2014, 10, 06, 12, 04, 56) dt = 06-Oct-2014 12:04:56 >> dt = dt + seconds((0:5)*1e-9) dt = Columns 1 through 2 06-Oct-2014 12:04:56 06-Oct-2014 12:04:56 Columns 3 through 4 06-Oct-2014 12:04:56 06-Oct-2014 12:04:56 Columns 5 through 6 06-Oct-2014 12:04:56 06-Oct-2014 12:04:56 >> dt.Format = 'dd-MMM-yyyy HH:mm:ss.SSSSSSSSS' dt = Columns 1 through 2 06-Oct-2014 12:04:56.000000000 06-Oct-2014 12:04:56.000000001 Columns 3 through 4 06-Oct-2014 12:04:56.000000002 06-Oct-2014 12:04:56.000000003 Columns 5 through 6 06-Oct-2014 12:04:56.000000004 06-Oct-2014 12:04:56.000000005 It's hard to say what the right way for you to do this is without context, but it can be done. You just have to remember that MATLAB uses floating point, and in many cases nanoseconds pushes the limits of double precision. * You are right that we will have to deal with "new" leap seconds as they are defined. The fact that they are unpredictably added is the reason why some would describe math on a leap second timeline as impossible to get correct, at least for times in the future. As you are probably aware, there is some thought that leap seconds are not a good idea, and so there may not be any new ones added, we'll just have to see. Complications like this are the reason why you have to go out of your way to opt in to using leap seconds in MATLAB -- most people just don't want to have to worry about the issues they raise. In any case, MATLAB will have to keep up and provide a way to know which ones are included in any given release. We're still thinking about the right way to do this, and are gathering feedback from customers who are actively using leaps seconds.
Rob replied on : 16 of 43
David: > I assume that is why you were using text objects to get tick labels with real exponents. Probably - I try different ways until it works without necessarily understanding why it works. :-) > I will add an enhancement request to have colorbars handle log scaling. Thanks! They Python copycats do this: http://matplotlib.org/examples/pylab_examples/hist2d_log_demo.html Would be fantastic to have similar capabilities in Matlab. As for my earlier comments about XTickLabels having multiple rows, here's a (bad quality, IDL I think) example of the type of thing I would love to do easily in Matlab: http://themis.ssl.berkeley.edu/summary.php?year=2013&month=10&day=07&hour=0024&sumType=tha&type=overview Sarah, didn't realize I was speaking to Matlab people! I found the video very useful, but that was that typo. :-) I presume my nanosecond resolution issue (entering nanoseconds as numbers not a string not showing odd nanoseconds) is reported as a bug to fix? As for the day of year calculation, date needs to be end of previous year (as Jan 1st is day of year 1), but this caldays works out slower that my faster way (but is accurate - not always true of the faster way)/ With the new datetime in a variety of ways, my original simple difference is the quickest by far (and a VAST improvement over datenum, so this is great! However it does have the potential to be wrong - more on that below.) t = datetime(2002,10,30,0,0,(0:86400)'); tic, doy2 = floor(days(t-datetime(t.Year-1,12,31))); toc tic, doy3 = caldays(between(datetime(t.Year-1,12,31),t,'days')); toc tic, t.Format = 'DDD'; doy4 = str2num(char(t)); toc Gives: Elapsed time is 0.015342 seconds. Elapsed time is 0.723682 seconds. Elapsed time is 0.848631 seconds. Instead of referencing last day of last year (datetime(t.Year-1,12,31)) we could do the non-real Jan-00th (datetime(t.Year,1,0)), but this takes longer to run - I presume because 0 is not an expected day of month and some internal check goes on. But I'd welcome any advice from Peter (who I'm guessing is also Matlab). As a side question, does datetime have any way to confirm is a string is an acceptable date string? i.e. would baulk at 2014-02-30? or a time of 12:63:00, or allowing seconds up to 61 is during a leap second or up to 60 if not. I've got my own routines for this type of check, but if there's a faster inbuilt way... Upon more reading and playing I'm liking these datetime arrays even more. I'm amused you have a quarter routine to return which quarter of year, and a ymd (while also having separate year, month, day routines) - but all useful. As such I don't feel bad asking for an enhancement request to have a day-of-year routine, or adding doy as a property of a datetime array (which would be my ultimate wish-list). I've tested out the leap second thing a bit, and it seems to work! Mostly at least - but there are items to be wary of as they do not work as one might expect. Must set up datetime as: t = datetime(2012,06,30,0,0,(0:86402),'TimeZone','UTCLeapSeconds'); which means my doy command above must become (can't mix datetimes of different timezones apparently): tic, doy = floor(days(t-datetime(t.Year-1,12,31,'TimeZone',t.TimeZone))); toc which is a little slower (but still vastly better than using datenum) Last leap second was mid 2012. t = datetime(2012,06,30,023,59,(59:62),'TimeZone','UTCLeapSeconds') gives 2012-06-30T23:59:59.000Z 2012-06-30T23:59:60.000Z 2012-07-01T00:00:00.000Z 2012-07-01T00:00:01.000Z which is perfect. Now I want day-of-year, so let's use my equation above: doy = floor(days(t-datetime(t.Year-1,12,31,'TimeZone',t.TimeZone))) gives 182 183 183 183 This is not what I'd expect... it should be 182 182 183 183. This tells me the Matlab DAYS command does not understand that not all days are exactly 24 hours (with leap seconds days of 86399, 86400, 86401 and I think even 86402 seconds are allowed . To be fair, the help page for days says number of fixed-length days at 24 hours. Perhaps another enhancement request should be that the days command checks to see if TimeZone is 'UTCLeapSeconds' and gives a warning the result may be incorrect if so. As another wishlist item, it'd be great if there was a command that could tell me if any of my times fall on a leap second. So let's try my earlier method and set t.Format = 'DDD' This gives an error: The date format for UTCLeapSeconds datetimes must be 'uuuu-MM-dd'T'HH:mm:ss.SSS'Z''. t.Day is correct and gives [30 30 1 1], while t.Month is also correct [6 6 7 7] And Sarah's earlier comment about caldays does work perfectly with leap seconds: caldays(between(datetime(t.Year-1,12,31,'TimeZone','UTCLeapSeconds'),t,'days')) gave [182 182 183 183] as expected So for speed for getting DOY reliably I'm at: if strcmp(t.TimeZone,'UTCLeapSeconds') doy = caldays(between(datetime(t.Year-1,12,31,'TimeZone','UTCLeapSeconds'),t,'days')) else doy = floor(days(t-datetime(t.Year-1,12,31))); % quicker for speed, but caldays way works end This could be faster if I knew there was no leap second between my value t and the start of that year, then the quicker way works. But my lesson from this - the absolutely bullet proof (but at the expense of computational speed) way of doing this is: doy = caldays(between(datetime(t.Year-1,12,31,'TimeZone',t.TimeZone),t,'days')) I'm still curious as to how I find out what leap seconds Matlab is aware of, as that's the only way I can convince myself that my installation of Matlab is aware of all leaps seconds (and any new ones that happen). I would strongly urge the Matlab people in charge of the datetime stuff and also CDF files to start working with the NASA Goddard folks at: http://cdf.gsfc.nasa.gov/html/matlab_cdf_patch.html Your CDF codes are far slower than then need to be (orders of magnitude) and at least up to 2014a (can't speak for 2014b) where out of date and incompatible with latest CDF versions. The NASA folks have Patches that run so much quicker but also have to deal with leap seconds, and therefore they supply their own leap second file. Would be good if that went away and they could use your one (or yours theirs, etc.). Regards, Rob
Rob replied on : 17 of 43
Got it. The quickest reliable way to get DOY is... doy = day(t, 'dayofyear') This does appear to cope with leap seconds correctly. :-) This beats my best by a few: t = datetime(2008,12,31,0,0,(0:1e5)','TimeZone','UTCLeapSeconds'); tic, doy1 = caldays(between(datetime(t.Year-1,12,31,'TimeZone',t.TimeZone),t,'days')); toc tic, doy2 = floor(days(dateshift(t,'start','day')-datetime(t.Year-1,12,31,'TimeZone',t.TimeZone))); toc tic, doy3 = round(days(dateshift(t,'start','day')-datetime(t.Year-1,12,31,'TimeZone',t.TimeZone))); toc tic, doy4 = day(t,'DayOfYear'); toc Elapsed time is 0.030044 seconds. Elapsed time is 0.024621 seconds. Elapsed time is 0.025822 seconds. Elapsed time is 0.017025 seconds. The first was the old reliable. Then it occurred to me I don't care about hours/mins/sec, just the day, so if I round the time to midnight at the start of the day it'd be quicker to calculate and not have to worry about leap seconds any further. But how do you round down a datetime array to get to midnight with datetime arrays? With datenum times I'd just floor(datenum(...)) and be good... but the floor command does not work with times. The solution seems to be this: dateshift(t,'start','day'), which retains the TimeZone of t. So then days(dateshift(t,'start','day')-datetime(t.Year-1,12,31,'TimeZone',t.TimeZone)) will give me a whole number of days right? After all that's a midnight time minus a midnight time. Except I get remaindres from whole numbers of 0 or 0.000011574074. Where's that rounding come from? But anyway, hence the need for the floor in my second value. But then I wondered about the rounding, I don't know which way it'll go, so should make it a round (not floor) command, despite it being a little slower. But all pointless as the day command works faster and is easier, and does not need me to specify time zones. So one by one all my questions are being solved. That leaves how to create a datetime array from strings of times, where any non-valid string time(i.e. month 13 or hour 24) is rejected or converted to NaT (Not a Time).
Peter Perkins replied on : 18 of 43
Rob, you said this: "I presume my nanosecond resolution issue (entering nanoseconds as numbers not a string not showing odd nanoseconds) is reported as a bug to fix?" Just to be clear, there's no bug, as my previous post explained. I think your "Got it" acknowledged that, but just making sure. "So then days(dateshift(t,’start’,'day’)-datetime(t.Year-1,12,31,’TimeZone’,t.TimeZone)) will give me a whole number of days right? After all that’s a midnight time minus a midnight time. Except I get remaindres from whole numbers of 0 or 0.000011574074. Where’s that rounding come from?" It's not rounding. It's the leap second at the end of 2008. >> 0.000011574074 * 86400 ans = 1 >> t = datetime(2008,12,31,23,59,(58:62)','TimeZone','UTCLeapSeconds') t = 2008-12-31T23:59:58.000Z 2008-12-31T23:59:59.000Z 2008-12-31T23:59:60.000Z 2009-01-01T00:00:00.000Z 2009-01-01T00:00:01.000Z >> isInALeapSecond = (t.Second >= 60) isInALeapSecond = 0 0 1 0 0 You're using the days function, which as the doc says, is really nothing more than (elapsed time)/86400s. By opting into leap seconds, you're outside the world where every day is 86400s long (also true if you opt into time zones that observe daylight saving time). If you want to count days on the calendar, then use calendar days like this: >> d = between(datetime(t.Year-1,12,31,'TimeZone',t.TimeZone),dateshift(t,'start','day'),'days'); >> d([1 end]) ans = 366d 1d As for converting from strings, all the fields need to be valid, or you'll get a Not-a-Time value. >> t = datetime({'2014-10-8 07:49:00' '2014-13-8 07:49:15' '2014-10-8 07:49:30' '2014-10-8 24:49:45'}) t = 08-Oct-2014 07:49:00 NaT 08-Oct-2014 07:49:30 NaT >> isnat(t) ans = 0 1 0 1 So strings are strict. On the other hand, it's often useful to have numeric input roll over or back as needed: >> datetime(2014,[10 13 10 10],8,[7 7 7 24],49,0:15:45) ans = 08-Oct-2014 07:49:00 08-Jan-2015 07:49:15 08-Oct-2014 07:49:30 09-Oct-2014 00:49:45
Faruk replied on : 19 of 43
Hi I agree with Giorgio, the plots look worse and pdf outputs are worse too. I am not sure how to adjust all of my thousands of scripts to to deal with it. There tons of compatibility issue with my old codes.Here is just one basic example Axes changes according to the last plotted line which is not default before. Think about you plot an image and then set axis tight. If you plot a line larger then the image region before it does not change the axis of the figure but new version update axis according to new line which i don't want. I understand that you try to push people to upgrade but this is not the way you should go. I think you create a bunch of compatibility issue. We need to spend lots of time to address all of them.
David Garrison replied on : 20 of 43
Faruk, I would like to hear more about plots and pdf output looking worse. Can you provide some additional detail? Yes, some things have changed in R2014b graphics. If I understand you correctly, the problem you described in relatively easy to fix. After you plot your image set the Axes properties XLimMode and YLimMode to 'manual'. That tells MATLAB you don't want it to recalculate the axis limits. Then when you plot your line the axis limits will not change even if the line is larger than the image.
Pierre replied on : 21 of 43
I have to agree with Faruk and Giorgio (on a mac 10.9.5). Text smoothing need to be off for the text to be legible on screen. Scatter plots have ridiculously small points, and these look like hexagons once exported to pdf. Circular points (plot(...,'ck') look like octogons... And I expect the worst for more complicated graphics. RIght now, I've already observed that points drawn on top of pcolor maps (or surfs) are horrid. While I really welcome the color changes that make Matlab more colorblind-friendly (and simply better looking), other changes in the graphics were neither necessary nor useful. Take another six months and come up with truly good graphics on any system, rather than push a crippled version. At least on OSX systems, R2014b can't be used to generate illustrations. Too bad since --at long last-- we got the retina text in the interface windows, a very welcome change!
Rob replied on : 22 of 43
Dan, you got to doy = day(t,’dayofyear’); before I did. :-) And Peter, just seen your post - I think I may have written mine while yours and Dan's were waiting for approval. Peter, thanks for the explanations. (My 'got it' comment was actually about finding doy = day(t,’dayofyear’); as I'd not seen you reply at that point). I'm all about the leap seconds as that's how spacecraft data comes down. So given rounding always rounds down, my best bet for round nearest ns (or any other unit) is the old trick of add 0.5ns to the value then let it round down? This is more theoretical than anything, I tend to work in no more than millisecond units. I still believe 'days' should give a warning if the datetime array is in UTCLeapSeconds in that days are not fixed length anymore. You say datetime will only work for valid strings and give NaT otherwise... yet when I do this: datetime('1970-06-30T23:59:60.000Z','TimeZone','UTCLeapSeconds') ans = 1970-07-01T00:00:00.000Z That's not good. The first leap second wasn't until 1972, so my time is invalid, but it did not give NaT. Also, while this gives me a datetime, following your example that you then give to isnat, when I try this: t= datetime({'2014-10-32 07:49:00' '2014-10-00 07:49:00' }) I get an "Error using datetime" (not a NaT) and it wants me to tell it the format despite me using the same date time string format of your example that does work. That's weird. Even if I tell it a format, it's not happy: >> t =datetime('2014-10-01 17:00:1.000','InputFormat','yyyy-MM-dd HH:mm:ss.SSS') t = 01-Oct-2014 17:00:01 Good, now let's change day of month to zero >> t =datetime('2014-10-00 17:00:1.000','InputFormat','yyyy-MM-dd HH:mm:ss.SSS') Error using datetime (line 593) Unable to parse date/time string '2014-10-00 17:00:1.000' using the format 'yyyy-MM-dd HH:mm:ss.SSS'. Now lets change doy of month to too high >> t =datetime('2014-10-32 17:00:1.000','InputFormat','yyyy-MM-dd HH:mm:ss.SSS') Error using datetime (line 593) Unable to parse date/time string '2014-10-32 17:00:1.000' using the format 'yyyy-MM-dd HH:mm:ss.SSS'. Why did these not give NaTs? Finally, any reason why the leap second format be: uuuu-MM-ddTHH:mm:ss.SSSZ Could the Z be made optional? The T should work as a T or a space, and I should not have to provide it all values... i.e. if I gave a time of '2014-10-08' I'd want it to give me a datetime array where the hours,mins,secs are all zero by default. Instead I've got to manually pad my time string with zeros? or '2014-10-08T10' to put hours at 10, but assume minutes and seconds are zero. Also, I can't do commands like t.Format = "HH:mm:ss.SSS" to display my UTCLeapSeconds times in other ways. e.g. We commonly plot times as uuu-DDDTHH:mm:ss.SSS, which I'd have to make up a string for myself. I still think the datetime array will be incredibly useful and fast, I'm just seeing if it can replace my own Matlab codes that do this kind of stuff. :-)
Rob replied on : 23 of 43
Using the above bug (where an incorrect seconds of 60 not on a leap second seems to roll over to the first of the next month rather than return NaT) I can establish what leap seconds Matlab is aware of. And as expected it's up to date. :-) yyyy = 1970:year(now); t = datetime([yyyy yyyy],1,1,'TimeZone','UTCLeapSeconds')'; % pre-allocate array fprintf('Known leap seconds are:\n') for y = 1:numel(yyyy); t(2*y-1) = datetime(sprintf('%4d-06-30T23:59:60.000Z',yyyy(y)),'TimeZone','UTCLeapSeconds'); t(2*y ) = datetime(sprintf('%4d-12-31T23:59:60.000Z',yyyy(y)),'TimeZone','UTCLeapSeconds'); end t = t(t.Second==60) [Not the most efficient code, but it quickly did what I wanted] So this 'feature' of Matlab lets me hardwire my Matlab code (that I update with each news about a new leap second) to know if the local Matlab version is aware of the latest using something based on above. This lead to further time questions: 1) How do you pre-allocate a datetime array? If this was using datenum, and I was doing every second of a day (or hoping I had data for) I'd pre-allocate with: t = NaN(86400,1); However, there is no NaT command. Which I find weird, I figured all NaN commands would have an equivalent version for NaT? So how do I preallocate an datetime array with NaTs? t = datetime(NaN(86400,1),NaN(86400,1),NaN(86400,1)) or t = datetime(NaN,NaN,NaN(86400,1)) ; use scalars on all but one works, but is not elegant. 2) I often what to print my time as a string, for logging, or on plots. What's the best way of doing that? Using above then: >> t(end) 2012-06-30T23:59:60.000Z But I can't use that directly in an fprintf statement. ( fprintf('%s',t(end)) does not work) I can't use datestr either: >> datestr(t(end),'yyyy-mm-ddTHH:MM:SS.FFF') 2012-06-30T23:59:59.000 ...which is the wrong time - to be expected as datestr never expects 60 seconds... So am I left to make up my own datestr (to millisecond resolution) such as: t_str = sprintf('%4d-%02d-%02dT:%02d:%02d:%06.3f',t(end).Year,t(end).Month,t(end).Day,t(end).Hour,t(end).Minute,t(end).Second) or t_str = sprintf('%s%06.3f',datestr(t(end),'yyyy-mm-ddTHH:MM:'),t(end).Second) or to account for rounding errors to milliscond accuracy: t_str = sprintf('%s%06.3f',datestr(t(end),'yyyy-mm-ddTHH:MM:'),t(end).Second+0.0005) (I'm with the team on not wanting to round up minutes, but I do want to round up fractions of second to my chosen resolution) Looking at the documentation, it seems Matlab expect people to use datestr with datetime arrays - therefore the fact it does not work with leap seconds seems to be an issue, and unlike the bug above where it round up a second to the next day, this one rounds down to the previous second. (I'm really trying to be helpful here, I run sanity checks on stuff before I use it, and my findings are showing these issues. Time is fundamental to my science, there is no room for any error whatsoever... hence reporting so the issues can be addressed. I realize the datetime is new, so I see this as helping to improve it, I'm not trying to have a go at Matlab, I love Matlab, have been using it for 17 years and spend hours a day on it. :-) )
Peter Perkins replied on : 24 of 43
Rob, this comment thread probably isn't the best medium for us to provide support for this new feature. One more quick answer, and then I'm going to suggest that you contact MathWorks support with questions that they'd be more than happy to help with. When creating datetimes from strings, if _at least one_ string was parsed successfully, then you'll get an array possibly with some NaTs in it. But if _none_ of the strings parsed successfully (this includes the case where there is only one string, and it failed), the assumption is that there's something funny going on, and you get an error instead of an array comprised entirely of NaTs, which would be of not much use.
Steve L replied on : 25 of 43
Rob, based on your comment "So given rounding always rounds down, my best bet for round nearest ns (or any other unit) is the old trick of add 0.5ns to the value then let it round down?" calling ROUND on your seconds data prior to constructing the datetime object may be of use to you. In this release, we introduced some new capability into ROUND:
Y = round(X,N) rounds to N digits

Y = round(X,N,type) specifies the type of rounding. Specify 'significant' to round to
N significant digits (counted from the leftmost digit). In this case, N must be
a positive integer.

Rounding pi to 3 decimal places:
>> Y = round(pi,3)
Y =
3.142
>> Y - 3.142
ans =
0
Rounding to 3 significant figures:
>> Y = round(pi,3, 'significant')
Y =
3.14
>> Y - 3.14
ans =
0
Stephane replied on : 26 of 43
Hi, I upgraded to R2014b, mainly for the graphics. Whenever I run a script which includes plotting I get the following message: \\ Warning: The DrawMode property will be removed in a future release. Use the SortMethod property instead. \\ Furthermore the plotting is excessively slow despite my having a powerful machine. Any help would be appreciated.
David Garrison replied on : 27 of 43
Pierre, Faruk, and Giorgio, We will look into the Mac display issue that you've reported and see what we can find out. In the meantime, make sure you have the most up-to-date drivers for your graphics cards.
NG replied on : 28 of 43
Stephane, I already noticed this while the prerelease was out. I also informed TMW about this. After a series of e-mails, they could reproduce it and confirmed this is an issue. However, as R2014b is out now, it is not improved. For this reason we will recommend our customers not to update to R2014b, as long as this issue persists.
David Garrison replied on : 29 of 43
Stephane, The SortMethod property is a replacement fro DrawMode. You can just replace the DrawMode property with SortMethod in your code. Regarding the plotting performance question, can you provide some additional information or an example of where you are seeing a difference in speed.
NG replied on : 30 of 43
David, Try to the following:
xx = randn(1e6, 1);
figure(10);
tic;
plot(xx,'x');
drawnow;
toc

After these commands, it takes about a minute before I am allowed to zoom. My result:
Elapsed time is 10.533855 seconds.

I know that it doesn't make sense to try to plot as many points. However, this was possible in older versions. Results for 2014a:
Elapsed time is 0.567253 seconds.

David Garrison replied on : 31 of 43
Some additional information on R2014b graphics rendering on Mac OSX 10.9.5. 1) There is an issue with certain NVIDIA cards where anti-aliasing does not appear when a plot is first drawn causing lines to look jagged. If you resize the figure, the plot will redraw and the lines will be smoothed. There is a fix for this problem that is expected to be in the next release. 2) We are working on some improved support for retinal displays. Those should be coming soon although I don't have a specific release date.
Charlotte replied on : 32 of 43
Hi there, I'm generally quite excited about the changes to the graphics. In particular, the new histograms are awesome! I also really like the change in behaviour of "hold on". I am, however, running into problems with printing figures (on OS X 10.9.5). These problems are: - When printing to eps, the file size has increased considerably. Admittedly, I am plotting a rather large data set (1200*139 data points), but the old system had no problem with this. For example, the following code results in a 3 MB file with R2012a and a 28.4 MB file with R2014b. Specifying the opengl renderer reduces the file size, but it is no longer a vector format.
w = randn(1200,139) + 1j*randn(1200,139);
plot(w,'.');
print -depsc test.eps

- The bounding box definition is no longer compatible with all eps interpreters. It seems to be fine (tight) with some programs such as Inkscape and when converting to pdf with ps2pdf, but other software such as OS X's Preview render it as a figure at the bottom of a letter sized sheet of paper. Finally, printing to pdf instead of eps solves the file size problem, but not the bounding box problem. I have tried to use "set(gcf,'PaperPositionMode','auto')", but I still get a pdf that is letter sized with a figure in the centre. In the mean time I am using png's for managable file sizes and a tight bounding box, but I would ultimately prefer a vector format. I appreciate any comments you might have on this issue.
AR replied on : 33 of 43
I have recently installed R2014b and look forward to trying the new graphics features. However, I can no longer produce publication-grade, high-resolution figures on OSX Mavericks (non-retina) with my standard workflow. Something has changed in the EPS export that has compromised the quality and the results do not look as good - after having spent a few days trying to find another solution, I am going to install R2014a.
Dominik Holenstein replied on : 34 of 43
Just a quick question for clarification regarding animatedline: This is the line from your example where blue is assigned to myLine.Color:
myLine.Color = blue;

But it should be:
myLine.Color = 'blue';

Is this correct? I am asking this because the first version is not working on my computer. Kind regards, Dominik
David Garrison replied on : 35 of 43
Dominik, Yes you are right. I don't know how I missed that. Thank you for letting me know. Dave
Ahmad replied on : 36 of 43
Thanks for the update to the Graphics system :) I have a problem with it though. I have a multi-monitor setup on ubuntu, and whenever I make a call to imshow, it randomly chooses a workspace and/or monitor to plot the figure. (just try imshow('peppers.png') twice). Its quite annoying! Any ideas how to fix this?
Bradley Steel replied on : 37 of 43
As with a few others, I'm having trouble with the default graphics not looking like those shown here - but on windows rather than mac. I assume this is to do with OpenGL versions: on all three computers I have tried (personal laptop and two work machines) MATLAB is defaulting to software OpenGL 1.1. Advice on updating drivers for graphics cards seems redundant as none of these machines have dedicated graphics cards - and yet Tableau for example still produces stunning graphics on them. On my laptop, switching opengl to hardware reports v3.1, but as soon as I try a plot command it switches back to software, with no explanation other than a line under opengl info reporting "known graphics driver issues". The work desktops (two different intel processors) don't even switch off software opengl. On my laptop, the Intel driver update program linked to by Mathworks (after some digging) just told me to go to Toshiba, and Toshiba tell me I have the latest display drivers - I haven't yet tried on the other machines given the standard workplace difficulty of getting admin rights. These setups don't seem at all unusual, and my laptop is a sandy bridge with HD3000 graphics: good enough for non-gaming applications, while the work machines are i7s from 2009 and 2011, one with HD2000. If I ever have time I'll investigate if there are software options to get above OpenGL 1.1 without hardware support, but given the importance here I would have expected more information from Mathworks about how to get their new system working. With three different computers to play on it's frustrating that none of them work out of the box, let alone after some digging.
Bradley Steel replied on : 38 of 43
Exploring the work side, I was mistaken and they have two different graphics cards; one rated for OpenGL 2.1 and the other for OpenGL4.1. The issue may relate to our use of remote desktop to connect to them (they're not set up with monitors etc themselves), with some webpages suggesting RDP can't handle OpenGL above v1. Has anyone else tried the new graphics system over remote desktop?
Bob Blaine replied on : 39 of 43
Hi Bradley, You are correct that Windows RDP currently only supports OpenGL 1.1, which doesn't support anti-aliasing, so the lines are not as smooth. Switching to hardware when running MATLAB through RDP does nothing, since RDP is not connected to the hardware drivers. Earlier versions of the OpenGL implementation in Intel graphics drivers had some stability issues that were enough of a concern that MATLAB Graphics switches to software OpenGL (and hence OpenGL 1.1) to avoid crashes, missing lines, and clipping problems. If the plots that you do are 2D lines, you might want to consider setting the Renderer property on your figure to painters to improve the quality. The painters renderer doesn't rely on graphics drivers, but there is a performance hit because the rendering is done on the CPU rather than the graphics hardware.
David Garrison replied on : 40 of 43
Ahmad, I don't think we can resolved your issue in this forum. Perhaps you should work with our Technical Support team on this one. Thanks, Dave
Bruce Elliott replied on : 41 of 43
I love the new colors, and the uitabs are something I've been requesting for years. The best new feature I've found, though, is one that I have not seen mentioned anywhere (maybe it's in the official Release Notes - I haven't read them through), but it's one that I've also been longing for: 3D plots now clip lines at the data axis limits rather than the axes object's edges!! Hooray!
Anne Fouilloux replied on : 42 of 43
Graphics are much larger when saved in a file. Our users are complaining about it. Do you have a way to create smaller eps files? (we also tried pdf but there are still much larger than before). We are running on linux red hat 6. We do not need high-quality figures... We use: print('example', '-depsc2'); With matlab 2013b: ls -lrt example.eps -rw-r--r-- 1 testuser users 65596 Dec 12 10:01 example.eps With matlab 2014b: -rw-rw-r--. 1 testuser users 239255 Dec 12 09:48 example.eps
David Garrison replied on : 43 of 43
Anne, If you don't need to resize the generated eps file, you can use the opengl renderer. It will reduce the size of the file in many cases because the file will contain an embedded image rather than the instructions required to redraw the figure. To use the opengl renderer when generating eps files you can either: 1) Set the figure's renderer property to 'opengl' 2) Use the '-opengl' option when calling the print command.