Combination of lambda function and plot3d(?)
I'm having trouble understanding why the following code doesn't work like I'd hoped:
def test1():
base_frame = point3d((.5,.5,1), color='red', size=10)
def f(x,y,t): return(sin(pi*x)*sin(pi*y)*e^(-t))
frames = []
for t in [0,1]:
pic = base_frame
pic += plot3d(lambda x,y:f(x,y,t), (x, 0, 1), (y, 0, 1))
#It works if you uncomment the next line:
#pic.save('/tmp/foo.png')
frames += [pic,]
return(frames)
What happens is that both the frames (or all of them if I create more than two) end up containing the last plot. It appears that the plot doesn't get "evaluated" when I want it to. So far, the only mechanism I've found that can force it to be evaluated is inserting a .show() or a .save(), which won't work to well in a larger loop.
Now, I understand that the function "f" I've got here could have been rendered as an expression rather than a function. Then there's no problem. But in the real program, things are more complicated, and (afict) I really need the lambda.
Can anyone help me understand what's happening here, and how I might get this to work?
---------- UPDATE -----------
I realize I haven't been all that clear (in my own mind, as well as in my explanation) of what the problem is here. I think there are two issues (1) Getting the "lambda" thing to work, and (2) getting the plot to "evaluate." Here are three updated test cases, which contain a function that actually requires the lambda: test1() does what I want, but at the price of having to save every frame to a file. test2() and test3() do get the plot3d function to evaluate, but in both of those cases, I lose the "lambda" functionality and so the function being plotted isn't right.
#
# Test file
#
# Make sure I'm using the same function in all three tests.
# I need a function that actually requires the use of lambda
var('x,y,t')
def f(x,y,t):
if x < .5: return(sin(pi*x)*sin(pi*y))
else: return(sin(pi*x)*sin(pi*y)*e^(-t))
# Might as well define the base frame here too
base_frame = point3d((.5,.5,1), color='red', size=10)
def test1():
frames = []
for t in [0,1]:
pic = base_frame
pic += plot3d(lambda x,y:f(x,y,t), (x, 0, 1), (y, 0, 1))
# This "save" appears to force the line above to be "evaluated"
pic.save('/tmp/foo.png')
frames += [pic,]
return(frames)
def test2():
frames = []
for t in [0,1]:
pic = base_frame
def g(x,y): return(f(x,y,t))
pic += plot3d(g(x,y), (x, 0, 1), (y, 0, 1))
frames += [pic,]
return(frames)
def test3():
frames = []
for t in [0,1]:
pic = base_frame
ff = lambda t:lambda x,y:f(x,y,t)
pic += plot3d(ff(t)(x,y), (x, 0, 1), (y ...

In your situation, can you replace the line "pic += plot3d(lambda x,y:f(x,y,t), (x, 0, 1), (y, 0, 1))" with lines like "def g(x,y): return f(x,y,t); pic += plot3d(g(x,y), ...)"?
Well, I tried it. It appeared to do the same thing as using the lambda. That is, my function evaluated x and y OK, but it didn't force the plot to be evaluated.
That's odd, because for me the two behave differently: if I enter your code in the notebook and then evaluate 'test1()[0]', I see different plots with your version vs. the version with "def g(x,y): ...".
It's possible that I'm not understanding what you suggested correctly. Or, that there's a difference between the command line and notebook? I updated the question, showing what I tried (test2). Let me know if this wasn't what you meant. Note that I'm doing this all in the command line.
In your test2, change the line "pic += ..." to "pic += plot3d(g(x,y), ...)". That change works for me both in the notebook and from the command line. (Right now, you're defining g(x,y) but using it anywhere.)