# Succinctly plotting a function defined in terms of many intermediate functions

I'm trying to plot a function that is in turn defined in terms of a lot of other functions, which each have a lot of variables. Here's a stylized example of the kind of thing I'm trying to do:

f1 = a Exp[b] c / Tanh[c - d]
f2 = f1 / (1 + f1)
f3 = Log[Tan[f2]] / (f2 f1)
f4 = f3 BesselJ[0, f2] / f1
Plot[f1 f2 / (f3 f4) /. {b -> 1, c -> 1, d -> 1}, {a, 0, 1}]


Of course, this doesn't work, because Mathematica doesn't "know" that final function depends on a, b, c, and d. So I need to fix it by defining functions everywhere. That will work, but it also turns the code into an unreadable mess:

f1[a_,b_,c_,d_] := a Exp[b] c / Tanh[c - d]
f2[a_,b_,c_,d_] := f1[a,b,c,d] / (1 + f1[a,b,c,d])
f3[a_,b_,c_,d_] := Log[Tan[f2[a,b,c,d]]] / (f2[a,b,c,d] f1[a,b,c,d])
f4[a_,b_,c_,d_] := f3[a,b,c,d] BesselJ[0, f2[a,b,c,d]] / f1[a,b,c,d]
Plot[f1[a,b,c,d] f2[a,b,c,d] / (f3[a,b,c,d] f4[a,b,c,d]) /. {b -> 1, c -> 1, d -> 1}, {a, 0, 1}]


Now it's far less obvious what the code is actually trying to do -- and the actual case I'm working on has even more arguments and more complexity, so the situation is a lot worse. I have to paste in the list of arguments dozens of times.

This can't possibly be the intended way to accomplish this task, right? Is there any way to accomplish the goal of the second batch of code while keeping it closer to the length of the first batch?

Clear["Global*"]

f1 = a Exp[b] c/Tanh[c - d];
f2 = f1/(1 + f1);
f3 = Log[Tan[f2]]/(f2 f1);
f4 = f3 BesselJ[0, f2]/f1;


If c == d then Tanh[c - d] == 0 and causes a division by zero. Also, you must use Evaluate since Plot has the attribute HoldAll

Attributes[Plot]


• In a Manipulate the control variables are local so you must use replacement rules to substitute the control variables into the external representation if it doesn't include explicit parameters. If you still have problems, post a question with a concrete example of the Manipulate` problem. Oct 6, 2023 at 0:14