How to modify the graph of a piecewise function correctly?

f[x_] := E^x /; -2 <= x < 0
f[x_] := f[x - 2] /; x > 0
f[x_] := f[x + 2] /; x < -2

Plot[{f[x], -x/8 + 1/2}, {x, -6, 4}]

The graph of the function drawn by the above code is as follows:

The precise and correct graph is as shown in the image below:

The issues with the graph plotted by the code are mainly as follows:

  1. At the boundary points of the piecewise intervals, the graph is not a vertical line segment but rather has no image at all. See the parts circled in red in the figure above.

  2. The right endpoint of each interval is not included; the graph should use an open circle at that point to indicate this, as shown by the yellow circles in the figure. However, it does not.

How should the code be modified so that the generated graph matches the correct, normal function graph shown above?

I would suggest the option Exclusions, but it does not work with your style of defining functions. Do real Piecewise definitions instead, which are built for symbolic computation. As for the open circles, you can do them only manually, I suspect.

You can modify your function:

f2[x_] := E^Mod[x, 2, -2]

And then use ExclusionsStyle:

Plot[f2[x], {x, -6, 4}, ExclusionsStyle -> Dashed]

testex.bmp (954 KB)

As for the circles, there might be other ways to use ExclusionsStyle or Exclusions, but I didn’t see anything obvious.

Here’s a mod to Eric’s approach to put circles at the right ends of the lines of the plot:

f2[x_] := E^Mod[x, 2, -2]
myplot = Plot[f2[x], {x, -6, 4}, ExclusionsStyle -> Dashed,
  PlotStyle -> 
   Directive[
    Arrowheads[{{0.01, 1, 
       Graphics[{White, EdgeForm[ColorData[101][1]], Disk[]}]}}]
    ]
  ] /. g : {___, Directive[___, _Arrowheads, ___], ___} :> (g /. Line -> Arrow)

It puts them at ALL the right end points, whether they deserve an open dot or not. You’ll have to manually put some conditions in, if you want to restrict which segments get dots (e.g, the last one on the right should not get one if x were to go up to 4.5).

Or you could remove the last dot with the following:

myplot // With[{pos = Last@Position[#, _Arrow]}, 
   ReplacePart[#, pos -> (Extract[#, pos] /. Arrow -> Line)]
   ] &

Adding the open circles:

f2[x_]:=E^Mod[x,2,-2]

Show[
  Plot[f2[x],{x,-6,4},ExclusionsStyle->Dashed,AxesOrigin->{0,0}],
  ListPlot[{{-4,1},{-2,1},{0,1},{2,1},{4,1}},PlotMarkers->"OpenMarkers"]
]

Thank you for providing the code. The approach is neat and fully meets the requirements.

You can draw the vertical segments manually using Line and mark open/closed endpoints with Point inside a Graphics overlay. Show[Plot[...], Graphics[{...}]] gives you full control over those boundary details.