1
$\begingroup$

I use NDSolve to solve several differential equations (same equation, but different defined constants) and then to plot the results. The dependent variable in my plots cover a different domain each time (e.g. in the first plot, my dependent variable runs $0.7\leq x\leq0.99$, $0.6\leq x\leq0.9$ in the second plot, and so on). I want to be able to compare the results on a single plot by stretching the dependent variable x so that the $x_{min}\rightarrow x_{max}$ covers the same domain.

Basically, I want to know given some NDSolve:

s = NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, y, {x, 0, 30}]
Plot[Evaluate[y[x] /. s], {x, 0, 30}, PlotRange -> All]

How do I write a dependent variable to stretch a plot of my solution horizontally? (I want to be able to replace the variable $x$ with $0.5x$ to stretch my plot horizontally. The Example above is not my problem, the notebook would be very long.)

Edit

The method by yohbs worked on the sample differential equation that I posted, but for some reason didn't work on my real problem.

My problem is

d4d[x_] := 
  (1/Log[1/x])Log[(1/16*16) + (1/8*32*(1/x - 1)) + (1/4*24*(1/x - 1)^2) + 
    (1/2*8*(1/x - 1)^3)] 

ωd = 2.5;
Ω = 0.5;
todayd = 0.7;
EQfracd = 0.69 todayd;
Hd = 1/todayd;

dddta[t_] := d4a'[t]
va[t_] := (a[t])^d4a[t]
vdota[t_] := D[(a[t])^d4a[t], t]

{sd1, sd2} = 
  NDSolve[
    {3/2 (a'[t]/a[t])^2 + a'[t]/a[t] vdotd[t]/vd[t] - ωd/8 (vdotd[t])^2 == 
     1/4 (2*(2 π^((d4d[t] - 1)/2))/Gamma[(d4d[t] - 1)/2]) Ω*3/(8 π) Hd*a[t]^-d4d[t], 
     a[todayd] == 1}, 
    a, {t, 0.01 EQfracd, todayd}, 
    MaxSteps -> 10^9]

ad = 
  Plot[Evaluate[a[t] /. sd2], {t, EQfracd, todayd}, 
    PlotRange -> {{EQfracd, 1}, {0.6,1.05}}, 
    Frame -> True, 
    PlotStyle -> {Cyan}]

This gives a plot that runs from $t=0.48 \rightarrow 0.7$ and has $a(0.7)=1$. I want to shift and stretch the plot in the horizontal, so that it runs from $t=0.69\rightarrow 1$. I tried

Plot[Evaluate[a[t/todayd]/.sd2], ...

but that changes the shape of the plot itself (and doesn't shift the plot horizontally). yohbs' method did shift the plot from $0.48<t<0.7\rightarrow 0.7<t<1$, but it also stretched the plot vertically as well.

$\endgroup$

closed as off-topic by Michael E2, MarcoB, C. E., Bob Hanlon, Öskå Sep 19 '15 at 11:28

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "This question arises due to a simple mistake such as a trivial syntax error, incorrect capitalization, spelling mistake, or other typographical error and is unlikely to help any future visitors, or else it is easily found in the documentation." – Michael E2, MarcoB, C. E., Bob Hanlon, Öskå
If this question can be reworded to fit the rules in the help center, please edit the question.

  • $\begingroup$ You can format inline code and code blocks by selecting the code and clicking the {} button above the edit window. The edit window help button ? is also useful for learning how to format your questions and answers. You may also find this this meta Q&A helpful $\endgroup$ – Michael E2 Sep 17 '15 at 1:19
  • 1
    $\begingroup$ Did you try Plot[Evaluate[y[0.5 x] /. s], {x, 0, 30}, PlotRange -> All], that is, replacing x by 0.5 x as you state you wish? $\endgroup$ – Michael E2 Sep 17 '15 at 1:20
  • $\begingroup$ I did. The function itself changes. $\endgroup$ – Bob Sep 18 '15 at 17:48
  • $\begingroup$ Are you looking for AspectRatio, then? Or maybe ImageSize? (What you say doesn't make sense: You say you want to change $x$ to $0.5x$, but you object to actually doing it. That change is a transformation of the function, so called I suppose because it transforms the function. Or at least that's how it appears to me.) $\endgroup$ – Michael E2 Sep 18 '15 at 18:04
  • $\begingroup$ Not Aspect Ratio. The plot as it is written runs from $x=0\rightarrow x=30$. I want the same plot with the same 5 peaks, but to run from $x=0\rightarrow x=10$ (I don't want to change the size of the window or the y-yalues, but only stretch/squeeze the x-values.). $\endgroup$ – Bob Sep 18 '15 at 23:17
1
$\begingroup$

The result of NDSolve is an InterpolatingFunction. You can get the its domain simply by accessing its first element:

s = NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, y, {x, 0, 30}];
fun = y /. First[s];
First[fun]
(*output: {{0,30.}}*)

Then, if you have a list of such functions, you can use Rescale to plot them. For example, here's a list of InterpolatingFunctions with different domains:

sList = Flatten@Table[y/.
  NDSolve[{y'[x] == -y[x] Cos[x + y[x]], y[0] == -0.5 + RandomReal[]},
   y, {x, -RandomReal[], RandomReal[]}], 
 {5}]

The domains are extracted as explained above

domains = First /@ First /@ sList;

And then you can plot:

Plot[Evaluate@Table[
     sList[[i]][Rescale[x, {0, 1}, domains[[i]]]],
   {i, 5}], {x, 0, 1}]

enter image description here

$\endgroup$
  • $\begingroup$ Thanks. I tried this. It worked on the sample problem I posted, but when I applied this to my longer problem, it stretched my plot in the vertical direction. $\endgroup$ – Bob Sep 19 '15 at 0:47
1
$\begingroup$

If it is just shifting and stretching then will the basic function transformations work for you?

s = NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, y, {x, 0, 30}];

Manipulate[
 Plot[Evaluate[yshift + ystretch y[xshift + xstretch x] /. s], {x, 0, 
   30},
  PlotRange -> {Automatic, {-2, 3}},
  ImageSize -> Medium,
  AxesOrigin -> {0, 0}],
 {{yshift, 0}, -2, 2, Appearance -> "Labeled"},
 {{ystretch, 1}, .5, 1.5, Appearance -> "Labeled"},
 {{xshift, 0}, 0, 2, Appearance -> "Labeled"},
 {{xstretch, 1}, .5, 1.5, Appearance -> "Labeled"}]

Correct? Or I have misunderstood the question?

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.