# Draw a surface using Gaston with a nonrectangular domain

Dear all,
I have the code:

using Gaston

X = LinRange(-1,1, 30) # 50
Y = LinRange(-1,1, 30)

x = [u for u in X, v in Y]
y = [v for u in X, v in Y]
z = [u^2+v^2  for u in X, v in Y]

#
surf(x, y, z, w = :l, lc = :turquoise,
Axes(xlabel = :x, ylabel = :y, zlabel = :z,zrange= "[*<0:1<*]",xrange= "[*<-1:1<*]",yrange= "[*<-1:1<*]",
#view= "60, 45, 1, 1",
xtics = """("-0.5" -0.5, "0.0" 0, "+0.5" 0.5) offset .25,-0.5""",
ytics = """("-0.5" -0.5, "0.0" 0, "+0.5" 0.5) offset -1.25,-0.5""",
view = "75, 30, 0.7, 2.1",
size = "1.1,1.",
xyplane = "at 0",
#pm3d = "depthorder",
hidden3d = :on,
key = :off))


Supose that I want to draw this surface in a nonrectangular domain, eg, for all u \in [-1,1] and 0 \leq v \leq 1-u. How can I adapt the code above?

I am not sure I understand the second inequality, since u is a range, not a constant. However, I think this example may help you:

Gnuplot does not need a rectangular domain to plot; all it needs is a list of coordinates. Let’s say we want to plot a circle; we can do it as follows:

Θ = LinRange(0, 2π, 100);
x1 = [cos(θ) for θ in Θ];
y1 = [sin(θ) for θ in Θ];
z1 = [1 for θ in Θ];
surf(x1, y1, z1)


This plot results:

x2 = [2cos(θ)+1 for θ in Θ];
y2 = [sin(θ)+1 for θ in Θ];
z2 = [2 for θ in Θ];
surf!(x2, y2, z2)


with the result:

Both plots have clearly non-rectangular domains. It’s often more convenient to think about sets of arbitrary (x,y,z) coordinates rather than a 2-D function evaluated on a matrix.

If you want a surface, then you can put the sets of coordinates in the rows of a matrix. Gnuplot will then draw lines between the corresponding sets of points:

surf([x1';x2'], [y1';y2'], [z1';z2'])


results in:

which is, again, a plot on a non-rectangular domain.

1 Like

Thank you so much for your response.
However, you don’t underestood my question.

Lets to think in a domain in \mathbb{R}^2 where 0 \leq x \leq 1 and 0 \leq y \leq x. Do you agree with me that we don’t have an rectangle? The region is a triangle, whose vertex are the points (0,0), (1,0) and (1,1).

My intention is plot the graph of a given function z=f(x,y) where (x,y) are in this triangle (the extremes of this region are not constants). Given a x in the rangle [0,1], the y-value varies in the range [0,x].

We usually plot a surface when the extremes are constants. But, in this case, how can we proceed?

What I need to adapt in my code to plot this suface?
Thank you.

Got it. I think the easiest way is to use the fact that gnuplot ignores NaNs when plotting.

f(x,y) = y < x ? cos(8x) + sin(8y) : NaN
x = LinRange(0, 1, 100);
y = LinRange(0, 1, 100);
surf(x, y, f, w = :pm3d)


produces this plot:

with a triangular domain.

The downside of this approach is that you have to redefine (or wrap) the function to return NaN for values outside the range you’re interested in. Pinging @lazarusA; he might know a better way.

The initial code is the following:

using Gaston

f(x,y) = y < x && y > x^2 ? x^2+y^2 : NaN
x = LinRange(-1, 1, 100);
y = LinRange(-1, 1, 100);

surf!(x, y, f,w = :pm3d)


But I want to plot without use the structure if-else. Is there another way to do this? Thank you!

I can’t think of any. Any particular reason why you want to avoid it?

If you have a little points, the is a problem; see below:

a little strange…

The region is a triangle,

Then I would do a Mesh, unfortunately today is already late. Maybe tomorrow I can take a look at it again.

Thank you so much!
Can be tomorrow.

Is the problem that the calculation is inefficient because most points are ignored? Or is it something else?

A more number of points, the calculation is ineficient.
To produce the figure below, I have used 1000 points on x and 1000 points in y.
I have a solution. But, it isn’t the better way…