Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I want to programmatically draw some objects outside the Plot area in my Plot's Epilog, like in this dummy:

enter image description here

I found PlotRangeClipping and hoped that would be the solution, but setting it to False only gives me a very little bit of extra space:

enter image description here

How can I get that extra space?

For extra credit: I want my arrows smaller and my text bigger. ArrowHeads give all kinds of sizes, but I can't seem to control it. Also, my text is positioned a bit more to the right than the arrows, but I'd like to align it left, so that I can use the same X-coordinate. Lastly, below's my code. Constructive criticism is welcome, if you're curious enough to read it :-).

dc1 = 0.1; dc2 = 0.6; period = 1; rc = 3; y0 = dc1; mint = -4; maxt = 20; 
maxt2 = maxt - (maxt - mint)/5; tsplit = 0; 
rectangleWave[t_, period_, duty_] := UnitBox[Mod[t/period, 1.]/(2. duty)];
pwm1[t_] := rectangleWave[t, period, dc1]; 
pwm2[t_] := rectangleWave[t, period, dc2]; 
pwm[t_, tsplit_] := Piecewise[{{pwm1[t], t < tsplit}, {pwm2[t], t >= tsplit}}];
step[t_, tstep_, dc1_, dc2_] := dc1 + (dc2 - dc1) UnitStep[t - tstep];

(* ripple functions *)
Clear[ripple, v1, v2, duty, t0, rc1]; 
r = Solve[{v1 + (1 - v1) (1 - E^(-duty t0/rc1)) == v2 && 
    v2 E^(-(1 - duty) t0/rc1) == v1 && ripple == v2 - v1}, {v1, v2, ripple}];
ripplemin[t0_, rc1_, duty_] = First[v1 /. r];
ripplemax[t0_, rc1_, duty_] = First[v2 /. r];
rippleampl[t0_, rc1_, duty_] = First[ripple /. r];
y0 = ripplemin[period, rc, dc1];

(* main function *)
ss = NDSolve[{rc  y'[t] + y[t] == step[t, tsplit, dc1, dc2], y[0] == dc1},
    y, {t, mint, maxt}]; 
s = NDSolve[{rc  y'[t] + y[t] == pwm[t, tsplit], y[mint] == y0}, 
    y, {t, mint, maxt}, MaxStepSize -> 0.05];

(* find end ripple *)
ripple = rippleampl[period, rc, dc2]; NumberForm[ripple, {3, 3}]
rpmin = ripplemin[period, rc, dc2];
rpmax = ripplemax[period, rc, dc2];

(* Plot *)
Plot[{pwm[t, tsplit], Evaluate[y[t] /. s], step[t, tsplit, dc1, dc2], 
    Evaluate[y[t] /. ss]}, {t, mint, maxt}, Exclusions -> None, 
    ImageSize -> {480, 300}, PlotRange -> All, PlotPoints -> 1000, 
    PlotStyle -> {Automatic, Automatic, Thick}, Axes -> {True, False}, 
    PlotRangeClipping -> False, 
    Epilog -> {{Table[{Dotted, Line[{{mint, i}, { maxt, i}}]}, {i, 0, 1, 0.2}]},
        {Dashed, Line[{{maxt2, rpmin}, {2 maxt, rpmin}}]}, 
        {Dashed, Line[{{maxt2, rpmax}, {2 maxt, rpmax}}]},
        {Text[NumberForm[ripple, {3, 3}], {maxt + 1, dc2}]},
        {Arrow[{{maxt + 0.1, rpmax + 0.1}, {maxt + 0.1, rpmax}}]},  
        {Arrow[{{maxt + 0.1, rpmin - 0.1}, {maxt + 0.1, rpmin}}]} }]
share|improve this question
2  
Try ImagePadding -> All, or setting the ImagePadding directly. –  rcollyer Aug 12 '12 at 13:04
    
@rcollyer - Doesn't work with All, but does with a numerica value. Thanks. –  stevenvh Aug 12 '12 at 13:14

3 Answers 3

up vote 7 down vote accepted

rcollyer gave me the right "magic word": ImagePadding does the trick. I tried

ImagePadding -> All

like he suggested, but for some reason that doesn't work. With explicit values:

ImagePadding -> {{0, 20}, {0, 0}}

it works OK. Parameters are left, right, bottom and top padding, resp.

Note that this still needs PlotRangeClipping to be False.

Thanks, rcollyer.

edit
I didn't notice it first, but with bottom padding set to 0 the bottom half of the x-axis labels is cut off:

enter image description here

Bug? Anyway, fixed by setting the value to 5 Simon hints to use All as parameters, which is much better than the random 5 I used. Thanks, Simon.

ImagePadding -> {{All, 20}, {All, All}}

enter image description here

share|improve this answer
    
There's a line in the movie Labyrinth, "say the right words," and sometimes it is exactly like that! :) –  rcollyer Aug 12 '12 at 14:21
    
@rcollyer bellsouthpwp.net/d/p/dptolar/friend.htm –  belisarius Aug 12 '12 at 16:29
    
@Verde - I entered "Friend" and MMA said "Friend" back. Isn't that sweet? :-) –  stevenvh Aug 13 '12 at 13:59
1  
@stevenvh Yeah, but never try a four letters word –  belisarius Aug 13 '12 at 14:16
2  
@stevenvh, you can use All for the individual elements to ensure sufficient space for the labels: ImagePadding -> {{All, 20}, {All, All}} –  Simon Woods Aug 15 '12 at 12:22

I would rather draw those Epilog things in a separate Graphics then combine them by Show:

mainplot = 
 Plot[{pwm[t, tsplit], Evaluate[y[t] /. s], step[t, tsplit, dc1, dc2],
    Evaluate[y[t] /. ss]}, {t, mint, maxt}, Exclusions -> None, 
  ImageSize -> {480, 300}, PlotRange -> All, PlotPoints -> 1000, 
  PlotStyle -> {Automatic, Automatic, Thick}, Axes -> {True, False}]

epilogplot = 
 Graphics[{{Table[{Dotted, Line[{{mint, i}, {maxt, i}}]}, {i, 0, 1, 0.2}]}, {Dashed, 
    Line[{{maxt2, rpmin}, {1.04 maxt, rpmin}}]}, {Dashed, 
    Line[{{maxt2, rpmax}, {1.04 maxt, rpmax}}]}, {Text[
     NumberForm[ripple, {3, 3}], {maxt + 1, 
      dc2}]}, {Arrow[{{maxt + 0.1, rpmax + 0.1}, {maxt + 0.1, 
       rpmax}}]}, {Arrow[{{maxt + 0.1, rpmin - 0.1}, {maxt + 0.1, 
       rpmin}}]}}]

Show[{mainplot, epilogplot}]

Mathematica graphics

The PlotRange -> All setting in mainplot will ensure all contents in mainplot and epilogplot not being clipped when they are combined in Show.

share|improve this answer

Another possibility is PlotRangePadding.

Plot[{pwm[t, tsplit], Evaluate[y[t] /. s], step[t, tsplit, dc1, dc2], 
 Evaluate[y[t] /. ss]}, {t, mint, maxt}, Exclusions -> None, 
 ImageSize -> {480, 300}, PlotRange -> All, PlotPoints -> 1000, 
 PlotStyle -> {Automatic, Automatic, Thick}, Axes -> {True, False}, 
 PlotRangeClipping -> False, 

 PlotRangePadding -> {2, 0.05}, 

 Epilog -> {{Table[{Dotted, Line[{{mint, i}, {maxt, i}}]}, {i, 0, 1, 
  0.2}]}, {Dashed, 
  Line[{{maxt2, rpmin}, {2 maxt, rpmin}}]}, {Dashed, 
  Line[{{maxt2, rpmax}, {2 maxt, rpmax}}]}, {Text[
  NumberForm[ripple, {3, 3}], {maxt + 1, 
  dc2}]}, {Arrow[{{maxt + 0.1, rpmax + 0.1}, {maxt + 0.1, 
   rpmax}}]}, {Arrow[{{maxt + 0.1, rpmin - 0.1}, {maxt + 0.1, 
   rpmin}}]}}]

enter image description here

share|improve this answer
2  
My only issue with PlotRangePadding is that it extends the axes, too. But, it works, so +1. –  rcollyer Aug 12 '12 at 14:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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