{"id":319,"date":"2015-10-13T16:46:54","date_gmt":"2015-10-13T20:46:54","guid":{"rendered":"https:\/\/blogs.mathworks.com\/graphics\/?p=319"},"modified":"2015-10-13T16:46:54","modified_gmt":"2015-10-13T20:46:54","slug":"fill-between","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/graphics\/2015\/10\/13\/fill-between\/","title":{"rendered":"Fill Between"},"content":{"rendered":"<div class=\"content\"><h3>Fill Between<\/h3><p>One question I'm often asked is how to fill the area between two plotted curves. It is possible to do this, but it involves some details which aren't obvious, so let's walk through what's involved.<\/p><p>First we need a simple example. I'm going to plot these two Bessel functions.<\/p><pre class=\"codeinput\">x = linspace(0,8,50);\r\ny1 = besselj(2,x);\r\ny2 = besselj(3,x);\r\nplot(x,y1)\r\nhold <span class=\"string\">on<\/span>\r\nplot(x,y2)\r\nhold <span class=\"string\">off<\/span>\r\nlegend(<span class=\"string\">'J_2'<\/span>,<span class=\"string\">'J_3'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/plot_between_example_01.png\" alt=\"\"> <p>I want to highlight all of the areas where the value of 3rd Bessel function is larger than the value of the 2nd. In other words, I want to fill the area above the blue curve and below the red curve.<\/p><p>To fill an area, we're going to want to use the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/fill.html\">fill function<\/a>. This function takes three arguments: X, Y, and Color. We can get these from our data by building a mask of the locations where y2 &gt; y1. Our Y values are going to be the Y's from each of the two curves at the locations in that mask. And we'll need two copies of the X. We also need to flip the second half because fill is going to go left to right along the bottom, and right to left along the top.<\/p><pre class=\"codeinput\">mask = y2 &gt; y1;\r\nfx = [x(mask), fliplr(x(mask))];\r\nfy = [y1(mask), fliplr(y2(mask))];\r\nhold <span class=\"string\">on<\/span>\r\nfill_color = [.929 .694 .125];\r\nfh = fill(fx,fy,fill_color);\r\nhold <span class=\"string\">off<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/plot_between_example_02.png\" alt=\"\"> <p>That's a start, but we can see some issues. The fill is drawing a black line over the curves. We can get rid of that by setting its EdgeColor to none.<\/p><pre class=\"codeinput\">fh.EdgeColor = <span class=\"string\">'none'<\/span>;\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/plot_between_example_03.png\" alt=\"\"> <p>But that still doesn't look right. What's happening is that the fill is on top of the curves. We can see that more clearly if we make our lines wider.<\/p><pre class=\"codeinput\">set(findobj(gca,<span class=\"string\">'Type'<\/span>,<span class=\"string\">'line'<\/span>),<span class=\"string\">'LineWidth'<\/span>,3);\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/plot_between_example_04.png\" alt=\"\"> <p>To fix that, we need to move it to the back. We can do that with the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/uistack.html\">uistack function<\/a>.<\/p><pre class=\"codeinput\">uistack(fh,<span class=\"string\">'bottom'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/plot_between_example_05.png\" alt=\"\"> <p>But we still have some work to do. Look at the little missing piece between X=3 and X=4. And it looks even worse if we zoom out.<\/p><pre class=\"codeinput\">cla\r\nx = linspace(0,4*pi,50);\r\ny1 = besselj(2,x);\r\ny2 = besselj(3,x);\r\nplot(x,y1)\r\nhold <span class=\"string\">on<\/span>\r\nplot(x,y2)\r\nlegend(<span class=\"string\">'J_2'<\/span>,<span class=\"string\">'J_3'<\/span>)\r\nxlim([0 inf])\r\n\r\nmask = y2 &gt; y1;\r\nfx = [x(mask), fliplr(x(mask))];\r\nfy = [y1(mask), fliplr(y2(mask))];\r\nfill_color = [.929 .694 .125];\r\nfh = fill(fx,fy,fill_color);\r\nfh.EdgeColor = <span class=\"string\">'none'<\/span>;\r\nuistack(fh,<span class=\"string\">'bottom'<\/span>)\r\nhold <span class=\"string\">off<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/plot_between_example_06.png\" alt=\"\"> <p>These two problems are happening because the two curves cross in between values in our data. We need to do interpolation to find the point where they cross and add that intersection point to the fill. They intersect at X=3.7689, but the nearest x value we have in the plot is 3.8468. This means that we need to do interpolation between the data values to figure out exactly where the lines cross so that we can put an accurate end on our filled area.<\/p><p>Let's get rid of that fill, and create a pair of helper functions for doing linear interpolation.<\/p><pre class=\"codeinput\">delete(fh)\r\n\r\nhold <span class=\"string\">on<\/span>\r\noutput = [];\r\n<span class=\"comment\">% Calculate t in range [0 1]<\/span>\r\ncalct = @(n) (n(3,1)-n(2,1))\/(n(3,1)-n(2,1)-n(3,2)+n(2,2));\r\n<span class=\"comment\">% Generate interpolated X and Y values<\/span>\r\ninterp = @(t,n) n(:,1) + t*(n(:,2) - n(:,1));\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/plot_between_example_07.png\" alt=\"\"> <p>Now we loop over the values and copy the ones where y2 &gt; y1. But as we do that, we look for the places where the lines cross. When we find one, we do linear interpolation to find the crossing point, and we add that to the points we're saving. The result looks like this:<\/p><pre class=\"codeinput\"><span class=\"keyword\">for<\/span> i=1:length(x)\r\n    <span class=\"comment\">% If y2 is below y1, then we don't need to add this point.<\/span>\r\n\t<span class=\"keyword\">if<\/span> y2(i) &lt;= y1(i)\r\n        <span class=\"comment\">% But first, if that wasn't true for the previous point, then add the<\/span>\r\n        <span class=\"comment\">% crossing.<\/span>\r\n        <span class=\"keyword\">if<\/span> i&gt;1 &amp;&amp; y2(i-1) &gt; y1(i-1)\r\n            neighborhood = [x(i-1), x(i); y1(i-1), y1(i); y2(i-1), y2(i)];\r\n            t = calct(neighborhood);\r\n            output(:,end+1) = interp(t,neighborhood);\r\n        <span class=\"keyword\">end<\/span>\r\n    <span class=\"keyword\">else<\/span>\r\n    <span class=\"comment\">% Otherwise y2 is above y1, and we do need to add this point. But first<\/span>\r\n    <span class=\"comment\">% ...<\/span>\r\n        <span class=\"comment\">% ... if that wasn't true for the previous point, then add the<\/span>\r\n        <span class=\"comment\">% crossing.<\/span>\r\n        <span class=\"keyword\">if<\/span> i&gt;1 &amp;&amp; y2(i-1) &lt;= y1(i-1)\r\n            neighborhood = [x(i-1), x(i); y1(i-1), y1(i); y2(i-1), y2(i)];\r\n            t = calct(neighborhood);\r\n            output(:,end+1) = interp(t,neighborhood);\r\n        <span class=\"keyword\">end<\/span>\r\n\r\n        <span class=\"comment\">% add this point.<\/span>\r\n        output(:,end+1) = [x(i); y2(i); y1(i)];\r\n    <span class=\"keyword\">end<\/span>\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><p>At this point we have an X array and two Y arrays (one for the top and one for the bottom), just like we did before. But they have those crossing points inserted in the correct places.<\/p><pre class=\"codeinput\">xout = output(1,:);\r\ntopout = output(2,:);\r\nbotout = output(3,:);\r\nfh = fill([xout fliplr(xout)],[botout fliplr(topout)],fill_color);\r\nfh.EdgeColor = <span class=\"string\">'none'<\/span>;\r\nuistack(fh,<span class=\"string\">'bottom'<\/span>)\r\nhold <span class=\"string\">off<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/plot_between_example_08.png\" alt=\"\"> <p>That looks much better.<\/p><p>We can easily put that into <a href=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/fill_between.m\">a function that we can reuse<\/a> with other plots, like this one:<\/p><pre class=\"codeinput\">theta = linspace(-2*pi,2*pi,150);\r\nc = cos(theta);\r\ns = sin(theta);\r\nplot(theta,c,<span class=\"string\">'--'<\/span>)\r\nhold <span class=\"string\">on<\/span>\r\nplot(theta,s,<span class=\"string\">':'<\/span>)\r\nhf = fill_between(theta,c,s);\r\nhf.FaceColor = [.875 .875 .875];\r\naxis <span class=\"string\">tight<\/span>\r\nhold <span class=\"string\">off<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/plot_between_example_09.png\" alt=\"\"> <p>... or this one:<\/p><pre class=\"codeinput\">y1 = sin(theta)  .\/ theta;\r\ny2 = sin(2*theta) .\/ theta;\r\nhl = plot(theta,[y1; y2]);\r\nhf = fill_between(theta,y1,y2);\r\nset(hl,<span class=\"string\">'LineWidth'<\/span>,3)\r\naxis <span class=\"string\">tight<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/plot_between_example_10.png\" alt=\"\"> <p>You can even switch the inputs to color the other regions.<\/p><pre class=\"codeinput\">hf(2) = fill_between(theta,y2,y1);\r\nhf(2).FaceColor = [.466 .674 .188];\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/plot_between_example_11.png\" alt=\"\"> <p>But maybe a bit of a white border between the curves and the fills would make it look nicer.<\/p><pre class=\"codeinput\">htmp = [copyobj(hl(1),gca), copyobj(hl(2),gca)];\r\nset(htmp,<span class=\"string\">'LineWidth'<\/span>,5,<span class=\"string\">'Color'<\/span>,<span class=\"string\">'white'<\/span>)\r\nuistack(htmp,<span class=\"string\">'down'<\/span>)\r\nuistack(htmp,<span class=\"string\">'down'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/plot_between_example_12.png\" alt=\"\"> <p>Once you know the basic idea, you can probably extend this to do lots of other interesting tricks.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_1e5d2208c4e640d7b650066c38d97f55() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='1e5d2208c4e640d7b650066c38d97f55 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 1e5d2208c4e640d7b650066c38d97f55';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2015 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_1e5d2208c4e640d7b650066c38d97f55()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2015b<br><\/p><\/div><!--\r\n1e5d2208c4e640d7b650066c38d97f55 ##### SOURCE BEGIN #####\r\n%% Fill Between\r\n% One question I'm often asked is how to fill the area between two plotted\r\n% curves. It is possible to do this, but it involves some details which\r\n% aren't obvious, so let's walk through what's involved.\r\n%\r\n% First we need a simple example. I'm going to plot these two Bessel\r\n% functions.\r\n%\r\nx = linspace(0,8,50);\r\ny1 = besselj(2,x);\r\ny2 = besselj(3,x);\r\nplot(x,y1)\r\nhold on\r\nplot(x,y2)\r\nhold off\r\nlegend('J_2','J_3')\r\n\r\n%%\r\n% I want to highlight all of the areas where the value of 3rd Bessel function \r\n% is larger than the value of the 2nd. In other words, I want to fill the \r\n% area above the blue curve and below the red curve.\r\n%\r\n% To fill an area, we're going to want to use the <https:\/\/www.mathworks.com\/help\/matlab\/ref\/fill.html fill function>. \r\n% This function takes three arguments: X, Y, and Color. We can get these\r\n% from our data by building a mask of the locations where y2 > y1. Our Y\r\n% values are going to be the Y's from each of the two curves at the\r\n% locations in that mask. And we'll need two copies of the X. We also need\r\n% to flip the second half because fill is going to go left to right along\r\n% the bottom, and right to left along the top.\r\n%\r\nmask = y2 > y1;\r\nfx = [x(mask), fliplr(x(mask))];\r\nfy = [y1(mask), fliplr(y2(mask))];\r\nhold on\r\nfill_color = [.929 .694 .125];\r\nfh = fill(fx,fy,fill_color);\r\nhold off\r\n\r\n%%\r\n% That's a start, but we can see some issues. The fill is drawing a black\r\n% line over the curves. We can get rid of that by setting its EdgeColor to\r\n% none.\r\n%\r\nfh.EdgeColor = 'none';\r\n\r\n%%\r\n% But that still doesn't look right. What's happening is that the fill is\r\n% on top of the curves. We can see that more clearly if we make our lines\r\n% wider.\r\n%\r\nset(findobj(gca,'Type','line'),'LineWidth',3);\r\n\r\n%%\r\n% To fix that, we need to move it to the back. We can do that with\r\n% the <https:\/\/www.mathworks.com\/help\/matlab\/ref\/uistack.html uistack function>.\r\n%\r\nuistack(fh,'bottom')\r\n\r\n\r\n%%\r\n% But we still have some work to do. Look at the little missing piece between X=3\r\n% and X=4. And it looks even worse if we zoom out.\r\ncla\r\nx = linspace(0,4*pi,50);\r\ny1 = besselj(2,x);\r\ny2 = besselj(3,x);\r\nplot(x,y1)\r\nhold on\r\nplot(x,y2)\r\nlegend('J_2','J_3')\r\nxlim([0 inf])\r\n\r\nmask = y2 > y1;\r\nfx = [x(mask), fliplr(x(mask))];\r\nfy = [y1(mask), fliplr(y2(mask))];\r\nfill_color = [.929 .694 .125];\r\nfh = fill(fx,fy,fill_color);\r\nfh.EdgeColor = 'none';\r\nuistack(fh,'bottom')\r\nhold off\r\n\r\n\r\n%% \r\n% These two problems are happening because the two curves cross in between values\r\n% in our data. We need to do interpolation to find the point where they\r\n% cross and add that intersection point to the fill. They intersect at\r\n% X=3.7689, but the nearest x value we have in the plot is 3.8468. \r\n% This means that we need to do interpolation between the data values to\r\n% figure out exactly where the lines cross so that we can put an accurate\r\n% end on our filled area.\r\n%\r\n% Let's get rid of that fill, and create a pair of helper functions for\r\n% doing linear interpolation.\r\n%\r\ndelete(fh)\r\n\r\nhold on\r\noutput = [];\r\n% Calculate t in range [0 1]\r\ncalct = @(n) (n(3,1)-n(2,1))\/(n(3,1)-n(2,1)-n(3,2)+n(2,2));\r\n% Generate interpolated X and Y values\r\ninterp = @(t,n) n(:,1) + t*(n(:,2) - n(:,1));\r\n\r\n%%\r\n% Now we loop over the values and\r\n% copy the ones where y2 > y1. But as we do that, we look for the places\r\n% where the lines cross. When we find one, we do linear interpolation to\r\n% find the crossing point, and we add that to the points we're saving. The \r\n% result looks like this:\r\n%\r\nfor i=1:length(x)\r\n    % If y2 is below y1, then we don't need to add this point.\r\n\tif y2(i) <= y1(i)\r\n        % But first, if that wasn't true for the previous point, then add the\r\n        % crossing.\r\n        if i>1 && y2(i-1) > y1(i-1)\r\n            neighborhood = [x(i-1), x(i); y1(i-1), y1(i); y2(i-1), y2(i)];\r\n            t = calct(neighborhood);\r\n            output(:,end+1) = interp(t,neighborhood);\r\n        end\r\n    else\r\n    % Otherwise y2 is above y1, and we do need to add this point. But first\r\n    % ...\r\n        % ... if that wasn't true for the previous point, then add the \r\n        % crossing.\r\n        if i>1 && y2(i-1) <= y1(i-1)\r\n            neighborhood = [x(i-1), x(i); y1(i-1), y1(i); y2(i-1), y2(i)];\r\n            t = calct(neighborhood);\r\n            output(:,end+1) = interp(t,neighborhood);\r\n        end\r\n        \r\n        % add this point.\r\n        output(:,end+1) = [x(i); y2(i); y1(i)];\r\n    end\r\nend\r\n\r\n%%\r\n% At this point we have an X array and two Y arrays (one for the top and\r\n% one for the bottom), just like we did before. But they have those\r\n% crossing points inserted in the correct places.\r\n%\r\nxout = output(1,:);\r\ntopout = output(2,:);\r\nbotout = output(3,:);\r\nfh = fill([xout fliplr(xout)],[botout fliplr(topout)],fill_color);\r\nfh.EdgeColor = 'none';\r\nuistack(fh,'bottom')\r\nhold off\r\n\r\n%%\r\n% That looks much better. \r\n%\r\n% We can easily put that into a function that we can reuse with other\r\n% plots, like this one:\r\n%\r\ntheta = linspace(-2*pi,2*pi,150);\r\nc = cos(theta);\r\ns = sin(theta);\r\nplot(theta,c,'REPLACE_WITH_DASH_DASH')\r\nhold on\r\nplot(theta,s,':')\r\nhf = fill_between(theta,c,s);\r\nhf.FaceColor = [.875 .875 .875];\r\naxis tight\r\nhold off\r\n\r\n%%\r\n% ... or this one:\r\ny1 = sin(theta)  .\/ theta;\r\ny2 = sin(2*theta) .\/ theta;\r\nhl = plot(theta,[y1; y2]);\r\nhf = fill_between(theta,y1,y2);\r\nset(hl,'LineWidth',3)\r\naxis tight\r\n\r\n%%\r\n% You can even switch the inputs to color the other regions.\r\nhf(2) = fill_between(theta,y2,y1);\r\nhf(2).FaceColor = [.466 .674 .188];\r\n\r\n%%\r\n% But maybe a bit of a white border between the curves and the fills would\r\n% make it look nicer.\r\n%\r\nhtmp = [copyobj(hl(1),gca), copyobj(hl(2),gca)];\r\nset(htmp,'LineWidth',5,'Color','white')\r\nuistack(htmp,'down')\r\nuistack(htmp,'down')\r\n\r\n%%\r\n% Once you know the basic idea, you can probably extend this to do lots of\r\n% other interesting tricks.\r\n\r\n##### SOURCE END ##### 1e5d2208c4e640d7b650066c38d97f55\r\n-->\r\n","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/graphics\/files\/feature_image\/plot_between_thumbnail.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>Fill BetweenOne question I'm often asked is how to fill the area between two plotted curves. It is possible to do this, but it involves some details which aren't obvious, so let's walk through what's... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/graphics\/2015\/10\/13\/fill-between\/\">read more >><\/a><\/p>","protected":false},"author":89,"featured_media":320,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[7],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/319"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/users\/89"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/comments?post=319"}],"version-history":[{"count":3,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/319\/revisions"}],"predecessor-version":[{"id":323,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/319\/revisions\/323"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/media\/320"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/media?parent=319"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/categories?post=319"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/tags?post=319"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}