Graphing Rational Functions

by R. Dover, IMSA

Edit your window values (xmin, xmax, ymin, and ymax) as desired. (Be sure to leave the semi-colons between these values.)  Then define your choices for both the numerator and denominator (separately).  Examples are given in magenta below.  Lastly, click on either ⌤ at the far right of the number pad on most keyboards OR press ⇧-⏎ (Mac) or ⇧-⌤ (Windows).

xmin=-5; xmax=5; ymin=-15; ymax=15;
numf[x_]:=(x - 3) (x - 1) (x + 2)
denf[x_]:=(x + 1) (x - 1) (x - 2)
RatsGrapher

initialization

Clear[f,  RatsGrapher];
Needs["Graphics`Colors`"];
Off[General::spell1];
\(RatsGrapher := 
Module[{asymp, \ nsols, nvalsint, \ 
          nvals, realnvalsint, dsols, \ dvalsint, \ realdvalsint, \ dvals, 
          holes, limvals, holestuff, holepl, \ vavals, \ va, \ vaback, plf, \ 
          pla}, 
Show[
          Graphics[
            Text[StringForm[\*""ƒ(x)=\!\(``\/``\)"", \ 
                TraditionalForm[HoldForm[Evaluate[numf[x]]]], \ 
                TraditionalForm[HoldForm[Evaluate[denf[x]]]]], \ {0, 0}, 
              TextStyle -> {FontSize -> 28, 
                  FontColor -> Blue}]], 
          AspectRatio -> 1/5, \ \ ImageSize -> 
            600]; 
asymp[x_] := 
          Evaluate[
            PolynomialQuotient[numf[x], \ denf[x], 
              x]]; 
nsols = 
          NSolve[numf[x] == 0, x]; 
nvalsint = 
          If[Length[nsols] ≥ 1, 
            x /. nsols, \ {}]; 
realnvalsint = 
          Re[nvalsint]; 
nvals = 
          Intersection[nvalsint, \ realnvalsint]; 
dsols = 
          NSolve[denf[x] == 0, x]; 
dvalsint = 
          If[Length[dsols] ≥ 1, \ 
            x /. dsols, \ {}]; 
realdvalsint = 
          Re[dvalsint]; 
dvals = 
          Intersection[dvalsint, \ 
            realdvalsint]; 
possholes = 
          Intersection[nvals, 
            dvals]; 

newva = {\ }; 
Table[
          If[Count[realnvalsint, \ possholes[\([k]\)]] < 
              Count[realdvalsint, \ 
                possholes[\([k]\)]], 
AppendTo[newva, \ 
              possholes[\([k]\)]], \ newva], \ {k, \ 1, \ 
            Length[possholes]}]; 
holes = 
          Complement[possholes, \ 
            newva]; 


limvals = 
          Table[Limit[numf[x]\/denf[x], \ 
              x -> \ holes[\([k]\)]], \ {k, \ 1, \ 
              Length[holes]}]; 
holestuff = 
          If[Length[holes] > 0, \ 
            Table[{{White, 
                  Disk[{holes[\([k]\)], \ 
                      limvals[\([k]\)]}, \ {\((xmax - xmin)\)/75, \ 
                      GoldenRatio\ \((ymax - ymin)\)/75}\ ]}, \ {Red, 
                  Thickness[ .006], 
                  Circle[{holes[\([k]\)], \ 
                      limvals[\([k]\)]}, \ {\((xmax - xmin)\)/75, 
                      GoldenRatio\ \((ymax - ymin)\)/75}]}}, \ {k, \ 1, \ 
                Length[holes]}], {}]; 
holepl = 
          Graphics[Flatten[holestuff, 1]]; 
vavals = 
          Complement[dvals, holes]; 
va = 
          Table[{Hue[0], \ Dashing[{ .03}], \ Thickness[ .01], 
              Line[{{vavals[\([k]\)], \ ymin}, \ {vavals[\([k]\)], \ 
                    ymax}}]}, \ {k, \ 1, \ 
              Length[vavals]}]; 
va = 
          If[Length[vavals] == 1, \ Flatten[va], 
            va]; 
vaback = 
          Table[{White, \ Thickness[ .012], \ 
              Line[{{vavals[\([k]\)], \ ymin}, \ {vavals[\([k]\)], \ 
                    ymax}}]}, \ {k, \ 1, 
              Length[vavals]}]; 
vaback = 
          If[Length[vavals] == 1, \ Flatten[vaback], \ 
            vaback]; 
plf = 
          Plot[numf[x]\/denf[x], \ {x, \ xmin, \ xmax}, 
            PlotRange -> {ymin, \ ymax}, 
            PlotStyle -> Thickness[ .01], \ 
            DisplayFunction -> Identity]; 
pla = 
          Plot[Evaluate[asymp[x]], \ \ {x, \ xmin, \ xmax}, 
            PlotRange -> {ymin, \ ymax}, \ 
            PlotStyle -> {Hue[0], Thickness[ .01], \ Dashing[{ .03}]}, 
            DisplayFunction -> Identity]; 
vertasymp = 
          Graphics[\ va]; 
vertback = 
          Graphics[vaback]; 
verttext = 
          If[Length[vavals] ≥ 1, 
            Table[Text[
                StringForm["x=``", 
                  NumberForm[vavals[\([k]\)], 
                    3]], \ {vavals[\([k]\)] +  .7, \ 
                  ymax - \((1/20)\) \((ymax - ymin)\)}, 
                TextStyle -> {FontSize -> 22, 
                    FontColor -> Blue}], \ {k, \ 1, \ 
                Length[vavals]}], \ {}]; 
asymptext = 
          Text[StringForm["y=``", TraditionalForm[asymp[x]]], \ {xmax, 
              ymin + \((1.2/20)\) \((ymax - ymin)\)}, {1, 0}, 
            TextStyle -> {FontSize -> 22, 
                FontColor -> Blue}]; 
asymplabel = 
          Text["asymp", \ {xmax\ , \ 
              ymin + \((2.9/20)\) \((ymax - ymin)\)}, {1, 0}, \ 
            TextStyle -> {FontSize -> 22, 
                FontColor -> Blue}]; 
holetext = 
          If[Length[holes] ≥ 1, \ 
            Table[Text[
                StringForm["{``,``}", NumberForm[holes[\([k]\)], 3], \ 
                  NumberForm[limvals[\([k]\)], 3]], \ {holes[\([k]\)], \ 
                  limvals[\([k]\)] - 2.5}, 
                TextStyle -> {FontSize -> 22, 
                    FontColor -> Blue}], \ {k, \ 1, \ 
                Length[holes]}], \ {}]; 
Show[{plf, \ pla, 
            vertback, \ vertasymp, holepl, \ Graphics[verttext], 
            Graphics[asymplabel], \ Graphics[asymptext], \ 
            Graphics[holetext]}, ImageSize -> 600, \ 
          DisplayFunction -> $DisplayFunction]]\)