Construct ternary grid, evaluate a function on the grid and contour plot in Matlab

你说的曾经没有我的故事 提交于 2019-12-01 01:36:42

I am the author of ternplot. As you have correctly surmised, ternpcolor does not do what you want, as it is built to grid data automatically. In retrospect, this was not a particularly wise decision, I've made a note to change the design. In the mean time this code should do what you want:

EDIT: I've changed the code to find the intersection of two curves rather than just one.

N = 10; x = linspace(0, 1, N); y = x;  % The grid intersections on your diagram are actually rectangularly arranged, % so meshgrid will build the intersections for us [xx, yy] = meshgrid(x, y); zz = 1 - (xx + yy);  % now that we've got the intersections, we can evaluate the function f1 = @(x, y) 2*x.^2 + 3*y.^2 + 0.1; Fxy1 = f1(xx, yy); Fxy1(xx + yy > 1) = nan;  f2 = @(x, y) 3*x.^2 + 2*y.^2; Fxy2 = f2(xx, yy); Fxy2(xx + yy > 1) = nan;  f3 = @(x, y) (3*x.^2 + 2*y.^2) * 1000; % different order of magnitude Fxy3 = f3(xx, yy); Fxy3(xx + yy > 1) = nan;  subplot(1, 2, 1) % This constructs the ternary axes ternaxes(5);  % These are the coordinates of the compositions mapped to plot coordinates [xg, yg] = terncoords(xx, yy); % simpletri constructs the correct triangles tri = simpletri(N);  hold on % and now we can plot trisurf(tri, xg, yg, Fxy1); trisurf(tri, xg, yg, Fxy2); hold off view([137.5, 30]);  subplot(1, 2, 2); ternaxes(5) % Here we plot the line of intersection of the two functions contour(xg, yg, Fxy1 - Fxy2, [0 0], 'r') axis equal 

EDIT 2: If you want to find the point of intersection between two contours, you are effectively solving two simultaneous equations. This bit of extra code will solve that for you (notice I've used some anonymous functions in the code above now, as well):

f1level = 1; f3level = 1000; intersection = fsolve(@(v) [f1(v(1), v(2)) - f1level; f3(v(1), v(2)) - f3level], [0.5, 0.4]); % if you don't have the optimization toolbox, this command works almost as well intersection = fminsearch(@(v) sum([f1(v(1), v(2)) - f1level; f3(v(1), v(2)) - f3level].^2), [0.5, 0.4]);  ternaxes(5) hold on contour(xg, yg, Fxy1, [f1level f1level]); contour(xg, yg, Fxy3, [f3level f3level]); ternplot(intersection(1), intersection(2), 1 - sum(intersection), 'r.'); hold off 

I have played a bit with the file exchange submission https://www.mathworks.com/matlabcentral/fileexchange/2299-alchemyst-ternplot.

if you just do this:

[x,y]=meshgrid(0:0.1:1); Fxy = 2*x.^2 +3 *y.^2; ternpcolor(x(:),y(:),Fxy(:)) 

You get:

The thirds axis is created exactly as you say (1-x-y) inside the ternpcolor function. There are lots of things to "tune" here but I hope it is enough to get you started.

Here is a solution using R and my package ggtern. I have also included the points within proximity underneath, for the purpose of comparison.

library(ggtern)  Fxy      = function(x,y){ 2*x^2 + 3*y^2 } x = y    = seq(0,1,length.out = 100) df       = expand.grid(x=x,y=y);  df$z     = 1 - df$x - df$y df       = subset(df,z >= 0) df$value = Fxy(df$x,df$y)  #The Intended Breaks breaks = pretty(df$value,n=10)  #Create subset of the data, within close proximity to the breaks df.sub = ldply(breaks,function(b,proximity = 0.02){   s = b - abs(proximity)/2; f = b + abs(proximity)/2   subset(df,value >= s & value <= f) })  #Plot the ternary diagram ggtern(df,aes(x,y,z)) +    theme_bw() +    geom_point(data=df.sub,alpha=0.5,color='red',shape=21) +    geom_interpolate_tern(aes(value = value,color=..level..), size = 1, n = 200,                         breaks    = c(breaks,max(df$value) - 0.01,min(df$value) + 0.01),                         base      = 'identity',                         formula   = value ~ poly(x,y,degree=2)) +   labs(title = "Contour Plot on Modelled Surface", x = "Left",y="Top",z="Right") 

Which produces the following:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!