{"id":423,"date":"2016-02-24T14:35:06","date_gmt":"2016-02-24T19:35:06","guid":{"rendered":"https:\/\/blogs.mathworks.com\/graphics\/?p=423"},"modified":"2017-09-03T17:50:34","modified_gmt":"2017-09-03T21:50:34","slug":"on-the-grid","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/graphics\/2016\/02\/24\/on-the-grid\/","title":{"rendered":"On the Grid"},"content":{"rendered":"<div class=\"content\"><p>One type of question that I'm often asked is about how to use various visualization techniques with what is sometimes called \"scatter data\". This is data that is a list of individual measurements. These measurements often have locations associated with them, but that's not enough for many visualization techniques. These techniques also want grid information. This is information about how the measurements connect to each other. Let's take a look at a couple of ways in which we can get this grid information.<\/p><p>First we'll need some example data. Here I have 250 measurements. Each one has a 2D location and a value.<\/p><pre class=\"codeinput\">npts = 250;\r\nrng <span class=\"string\">default<\/span>\r\nx = 2*randn(npts,1);\r\ny = 2*randn(npts,1);\r\nv = sin(x) .* sin(y);\r\n<\/pre><p>Scatter data, which is sometimes known as column data, gets its name from the fact that the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/scatter.html\">scatter plot<\/a> is the one visualization technique which is really designed for this type of data.<\/p><pre class=\"codeinput\">scatter(x,y,36,v,<span class=\"string\">'filled'<\/span>)\r\ncolorbar\r\nxlim([-2*pi 2*pi])\r\nylim([-2*pi 2*pi])\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/on_the_grid_01.png\" alt=\"\"> <p>You can sort of see the pattern of v in that picture. If you squint hard enough. But it'd be a lot nicer if we had colors in between the dots. The <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/pcolor.html\">pcolor function<\/a> can draw that kind of picture, but it needs a particular type of input known as a \"structured grid\". We can create this type of grid by using the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/meshgrid.html\">meshgrid function<\/a>.<\/p><pre class=\"codeinput\">[xg,yg] = meshgrid(linspace(-2*pi,2*pi,125));\r\nsize(xg)\r\nsize(yg)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n   125   125\r\n\r\n\r\nans =\r\n\r\n   125   125\r\n\r\n<\/pre><p>But that's just the grid. That's not enough. We also need to get our values onto the grid. One good way to do this is with scatteredInterpolant.<\/p><pre class=\"codeinput\">F = scatteredInterpolant(x,y,v);\r\nvg = F(xg,yg);\r\nh = pcolor(xg,yg,vg);\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/on_the_grid_02.png\" alt=\"\"> <p>We don't really want to see the grid here, so I'll turn it off.<\/p><pre class=\"codeinput\">h.EdgeColor = <span class=\"string\">'none'<\/span>;\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/on_the_grid_03.png\" alt=\"\"> <p>And add a colorbar so we can see what values we're getting.<\/p><pre class=\"codeinput\">colorbar\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/on_the_grid_04.png\" alt=\"\"> <p>That looks pretty good, but not great. For one thing, the range of values is way too large. We can't possibly have sin(x)*sin(y) reaching values less than -2, can we?<\/p><pre class=\"codeinput\">caxis([-1 1])\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/on_the_grid_05.png\" alt=\"\"> <p>And while the middle of the picture is pretty good, look at that big yellow blob in the upper left and the big blue blob on the bottom. Where did those come from?<\/p><p>Both of these issues are because out at the edges of the grid scatteredInterpolant is extrapolating past the values we gave it, rather than interpolating between them. Extrapolation is almost always a fairly dicey operation. To do it successfully, you really need to know a lot about the data you're working with, and use a lot of care in choosing your extrapolation function.<\/p><p>Often it's better to just discard the parts of the grid which require extrapolation. That's actually pretty easy to do. We just need to insert nans into the values at those points on the grid. We can find those points on the grid by using <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/convhull.html\">convhull<\/a> and <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/inpolygon.html\">inpolygon<\/a>.<\/p><pre class=\"codeinput\">p = convhull(x,y);\r\nxp = x(p);\r\nyp = y(p);\r\ninmask = inpolygon(xg(:),yg(:), xp,yp);\r\nvg(~inmask) = nan;\r\nh = pcolor(xg,yg,vg);\r\nh.EdgeColor = <span class=\"string\">'none'<\/span>;\r\nxlim([-2*pi 2*pi])\r\nylim([-2*pi 2*pi])\r\ncaxis([-1 1])\r\ncolorbar\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/on_the_grid_06.png\" alt=\"\"> <p>I could use either the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/boundary.html\">boundary function<\/a> or the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/alphashape.html\">alphaShape function<\/a> instead of convhull here.<\/p><p>As you can see, boundary will be more aggressive about removing portions of the grid which are far away from any sample points. It also has a parameter which lets you adjust that.<\/p><pre class=\"codeinput\">b = boundary(x,y);\r\ninmask = inpolygon(xg(:),yg(:), x(b),y(b));\r\n\r\nvg = F(xg,yg);\r\nvg(~inmask) = nan;\r\nh = pcolor(xg,yg,vg);\r\nh.EdgeColor = <span class=\"string\">'none'<\/span>;\r\nxlim([-2*pi 2*pi])\r\nylim([-2*pi 2*pi])\r\ncaxis([-1 1])\r\ncolorbar\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/on_the_grid_07.png\" alt=\"\"> <p>Another thing that is very important when you're gridding scatter data is choosing the right grid resolution. The scatteredInterpolant is going to work best when the resolution of the grid is close to the spacing of your original sample points. A grid that's too fine usually isn't a big problem (except for the amount of memory you consume), but if your grid is much coarser than the spacing of the input points, then you may see aliasing artifacts. That's because the scatteredInterpolant doesn't really low-pass filter for you. This issue can become quite challenging when the spacing between your sample points varies widely. A good grid resolution for one area of your data might not be appropriate for another area.<\/p><p>But the \"structured grid\" isn't the only type of grid available to us. There's also what's known as an \"unstructured grid\". In a structured grid, we just lay out the values in a 2D array, and know that each one is connected to its immediate neighbors. In an unstructured mesh, we'll keep our columns of data values, and add an extra variable that lists how they're connected.<\/p><p>BTW, I've always thought this naming convention was a little silly because the whole point of an unstructured grid is that you have to spell out the structure in detail. The word \"unstructured\" doesn't seem like a good description of that.<\/p><p>The simplest type of unstructured grid is a \"triangle mesh\". In a triangle mesh, we have Nx3 array which is a list of triangles which each connect three of the original points. One easy way to create a triangle mesh is to use the delaunayTriangulation function.<\/p><pre class=\"codeinput\">dt = delaunayTriangulation(x,y);\r\n<\/pre><p>Once we have our triangle mesh, we can draw it using the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/trisurf.html\">trisurf function<\/a>.<\/p><pre class=\"codeinput\">h = trisurf(dt.ConnectivityList,x,y,zeros(npts,1),v);\r\nh.FaceColor = <span class=\"string\">'interp'<\/span>;\r\nview(2)\r\nxlim([-2*pi 2*pi])\r\nylim([-2*pi 2*pi])\r\ncaxis([-1 1])\r\ncolorbar\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/on_the_grid_08.png\" alt=\"\"> <p>Again, I'll hide the grid.<\/p><pre class=\"codeinput\">h.EdgeColor = <span class=\"string\">'none'<\/span>;\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/on_the_grid_09.png\" alt=\"\"> <p>There are some advantages to each of these two approaches.<\/p><p>The triangle mesh is nice and compact, and it often has fewer gridding artifacts. In particular, it naturally handles that case where the spacing between the points varies a lot by placing more triangles where the data is sampled more finely.<\/p><p>On the other hand, MATLAB has more visualization techniques which work on a structured grid. For example, I could use one of the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/contour-plots-1.html\">contour functions<\/a> on the structured grid, but MATLAB doesn't come with a contour function that will work on triangle meshes, although you can find some <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/10408-contours-for-triangular-grids\">on the File Exchange<\/a>.<\/p><p>These two examples are just an introduction to the powerful tools that MATLAB provides for gridding scatter data. If you find one of them useful, you might want to explore the different options that scatteredInterpolant accepts, and some of the <a title=\"https:\/\/www.mathworks.com\/help\/matlab\/interpolation-1.html (link no longer works)\">other functions<\/a> that are available. And you might also want to start a conversation on <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/answers\/\">MATLAB Answers<\/a>. There are a number of people there who have experience with gridding different types of data.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_6caac5774e4848f39a1e3e9a6178ca97() {\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='6caac5774e4848f39a1e3e9a6178ca97 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 6caac5774e4848f39a1e3e9a6178ca97';\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 2016 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_6caac5774e4848f39a1e3e9a6178ca97()\"><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\n6caac5774e4848f39a1e3e9a6178ca97 ##### SOURCE BEGIN #####\r\n%%\r\n% One type of question that I'm often asked is about how to use various\r\n% visualization techniques with what is sometimes called \"scatter data\".\r\n% This is data that is a list of individual measurements. These\r\n% measurements often have locations associated with them, but that's not\r\n% enough for many visualization techniques. These techniques also want grid\r\n% information. This is information about how the measurements connect to\r\n% each other. Let's take a look at a couple of ways in which we can get\r\n% this grid information.\r\n%\r\n% First we'll need some example data. Here I have 250 measurements. Each\r\n% one has a 2D location and a value.\r\n%\r\nnpts = 250;\r\nrng default\r\nx = 2*randn(npts,1);\r\ny = 2*randn(npts,1);\r\nv = sin(x) .* sin(y);\r\n\r\n%%\r\n% Scatter data, which is sometimes known as column data, gets its name from\r\n% the fact that \r\n% the <https:\/\/www.mathworks.com\/help\/matlab\/ref\/scatter.html scatter plot> \r\n% is the one visualization technique which is really designed for this type\r\n% of data.\r\n%\r\nscatter(x,y,36,v,'filled')\r\ncolorbar\r\nxlim([-2*pi 2*pi])\r\nylim([-2*pi 2*pi])\r\n\r\n%%\r\n% You can sort of see the pattern of v in that picture. If you squint hard\r\n% enough. But it'd be a lot nicer if we had colors in between the dots. The\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/pcolor.html pcolor function>\r\n% can draw that kind of picture, but it needs a particular type of input \r\n% known as a \"structured grid\". We can create this type of grid by using\r\n% the <https:\/\/www.mathworks.com\/help\/matlab\/ref\/meshgrid.html meshgrid\r\n% function>. \r\n%\r\n[xg,yg] = meshgrid(linspace(-2*pi,2*pi,125));\r\nsize(xg)\r\nsize(yg)\r\n\r\n%%\r\n% But that's just the grid. That's not enough. We also need to get our\r\n% values onto the grid. One good way to do this is with\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/scatteredinterpolant-class.html\r\n% scatteredInterpolant>.\r\n%\r\nF = scatteredInterpolant(x,y,v);\r\nvg = F(xg,yg);\r\nh = pcolor(xg,yg,vg);\r\n\r\n%%\r\n% We don't really want to see the grid here, so I'll turn it off.\r\n%\r\nh.EdgeColor = 'none';\r\n\r\n%%\r\n% And add a colorbar so we can see what values we're getting.\r\n%\r\ncolorbar\r\n\r\n%%\r\n% That looks pretty good, but not great. For one thing, the range of values \r\n% is way too large. We\r\n% can't possibly have sin(x)*sin(y) reaching values less than -2, can we?\r\n%\r\ncaxis([-1 1])\r\n\r\n%%\r\n% And while the middle of the picture is pretty good, look at that big yellow \r\n% blob in the upper left and the big blue blob on the bottom. Where did \r\n% those come from?\r\n% \r\n% Both of these issues are because out at the edges of the grid scatteredInterpolant is \r\n% extrapolating past the values we gave it, rather than interpolating\r\n% between them. Extrapolation is almost always a\r\n% fairly dicey operation. To do it successfully, you really need to know a\r\n% lot about the data you're working with, and use a lot of care in choosing \r\n% your extrapolation function.\r\n%\r\n% Often it's better to just discard the parts of the grid which require\r\n% extrapolation. That's actually pretty easy to do. We just need to insert\r\n% nans into the values at those points on the grid. We can find those\r\n% points on the grid by using\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/convhull.html convhull> and \r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/inpolygon.html inpolygon>.\r\n%\r\np = convhull(x,y);\r\nxp = x(p);\r\nyp = y(p);\r\ninmask = inpolygon(xg(:),yg(:), xp,yp);\r\nvg(~inmask) = nan;\r\nh = pcolor(xg,yg,vg);\r\nh.EdgeColor = 'none';\r\nxlim([-2*pi 2*pi])\r\nylim([-2*pi 2*pi])\r\ncaxis([-1 1])\r\ncolorbar\r\n\r\n%%\r\n% I could use either the <https:\/\/www.mathworks.com\/help\/matlab\/ref\/boundary.html boundary\r\n% function> or the <https:\/\/www.mathworks.com\/help\/matlab\/ref\/alphashape.html alphaShape function> instead of convhull here.\r\n%\r\n% As you can see, boundary will be more aggressive about removing\r\n% portions of the grid which are far away from any sample points. It also\r\n% has a parameter which lets you adjust that.\r\n%\r\nb = boundary(x,y);\r\ninmask = inpolygon(xg(:),yg(:), x(b),y(b));\r\n\r\nvg = F(xg,yg);\r\nvg(~inmask) = nan;\r\nh = pcolor(xg,yg,vg);\r\nh.EdgeColor = 'none';\r\nxlim([-2*pi 2*pi])\r\nylim([-2*pi 2*pi])\r\ncaxis([-1 1])\r\ncolorbar\r\n\r\n%%\r\n% Another thing that is very important when you're gridding scatter data is \r\n% choosing the right grid resolution. The scatteredInterpolant is going to\r\n% work best when the resolution of the grid is close to the spacing of your\r\n% original sample points. A grid that's too fine usually isn't a big\r\n% problem (except for the amount of memory you consume), but if your grid is \r\n% much coarser than the spacing of the input\r\n% points, then you may see aliasing artifacts. That's because the\r\n% scatteredInterpolant doesn't really low-pass filter for you. This issue can\r\n% become quite challenging when the spacing between your sample points\r\n% varies widely. A good grid resolution for one area of your data might not\r\n% be appropriate for another area.\r\n%\r\n\r\n%%\r\n% But the \"structured grid\" isn't the only type of grid available to us.\r\n% There's also what's known as an \"unstructured grid\". In a structured\r\n% grid, we just lay out the values in a 2D array, and know that each one is\r\n% connected to its immediate neighbors. In an unstructured mesh, we'll keep\r\n% our columns of data values, and add an extra variable that lists how\r\n% they're connected. \r\n%\r\n% BTW, I've always thought this naming convention was a little silly \r\n% because the whole point of an unstructured grid is that you have to spell \r\n% out the structure in detail. The word \"unstructured\" doesn't seem like a\r\n% good description of that.\r\n%\r\n% The simplest type of unstructured grid is a \"triangle mesh\". In a triangle\r\n% mesh, we have Nx3 array which is a list of triangles which each connect three of the\r\n% original points. One easy way to create a triangle mesh is to use the \r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/delaunaytriangulation-class.html\r\n% delaunayTriangulation function>.\r\n%\r\ndt = delaunayTriangulation(x,y);\r\n\r\n%%\r\n% Once we have our triangle mesh, we can draw it using the\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/trisurf.html trisurf function>.\r\n% \r\nh = trisurf(dt.ConnectivityList,x,y,zeros(npts,1),v);\r\nh.FaceColor = 'interp';\r\nview(2)\r\nxlim([-2*pi 2*pi])\r\nylim([-2*pi 2*pi])\r\ncaxis([-1 1])\r\ncolorbar\r\n\r\n%%\r\n% Again, I'll hide the grid.\r\n%\r\nh.EdgeColor = 'none';\r\n\r\n%%\r\n% There are some advantages to each of these two approaches. \r\n%\r\n% The triangle mesh is nice and compact, and it often has fewer gridding\r\n% artifacts. In particular, it naturally handles that case where the spacing\r\n% between the points varies a lot by placing more triangles where the data\r\n% is sampled more finely.\r\n%\r\n% On the other hand, MATLAB has more visualization techniques which work on a\r\n% structured grid. For example, I could use one of the \r\n% <https:\/\/www.mathworks.com\/help\/matlab\/contour-plots-1.html contour\r\n% functions> on the structured grid, but MATLAB doesn't come with a contour function\r\n% that will work on triangle meshes, although you can find some <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/10408-contours-for-triangular-grids on the File\r\n% Exchange>.\r\n%\r\n% These two examples are just an introduction to the powerful tools that \r\n% MATLAB provides for gridding scatter data. If you find one of them useful,\r\n% you might want to explore the different options that\r\n% scatteredInterpolant accepts, and some of the\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/interpolation-1.html other\r\n% functions> that are available. And you might also want to start a\r\n% conversation on <https:\/\/www.mathworks.com\/matlabcentral\/answers\/ MATLAB\r\n% Answers>. There are a number of people there who have experience with\r\n% gridding different types of data.\r\n%\r\n%\r\n##### SOURCE END ##### 6caac5774e4848f39a1e3e9a6178ca97\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/graphics\/files\/feature_image\/grid_thumbnail.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>One type of question that I'm often asked is about how to use various visualization techniques with what is sometimes called \"scatter data\". This is data that is a list of individual measurements.... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/graphics\/2016\/02\/24\/on-the-grid\/\">read more >><\/a><\/p>","protected":false},"author":89,"featured_media":425,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[5],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/423"}],"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=423"}],"version-history":[{"count":11,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/423\/revisions"}],"predecessor-version":[{"id":710,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/423\/revisions\/710"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/media\/425"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/media?parent=423"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/categories?post=423"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/tags?post=423"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}