19

October 31st

Note: Below is the original question, but after some feedback I have progressed somewhat and posted an answer to demonstrate what I've learnt since. My answer presents an encapsulated solution. I'm posting it here because the original question was in the context of being able to create diagrams for demonstrating Riemann sums.

These questions here are where I was a week ago and my answer is where I am now. The title remains relevant. A search on placing rectangles on a plot or on Riemann Sums will turn up this page and there are some useful answers here.

I'm sorry if people think I've confused the question, but I think this is what happens when you're on a steep learning curve and the page was kind of documenting that. What seem like simple questions now were quite perplexing a week ago. I've edited this and my answer comprehensively in order to simplify matters.

October 23rd

Q(1) If there was a simple way to add the in-between lines to the rectangles in the attempt on the left, I would be finished. The problem with the solution on the right is the stacked environment doesn't like my original graph so I placed it in it's own axis environment and then had trouble with the curve matching the rectangles.

I tried the solution on the right mainly to get the colours right, but quickly realised drawing the upper rectangles before the lower ones gave what I wanted with the solution on the left. If drawing those lines is the only way to go then fair enough, but is there a systematic way to get them as part of the plot?

Q(2) Can I get the values for the heights of the rectangles from my plot equation rather than calculating and typing them all in by hand?

MWE 1 Output

MWE 1 Output

MWE 1 Code

\documentclass{standalone}

\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{pgfplots}
\usepackage{mathtools}

\pgfplotsset{compat=1.9}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
    xtick={0,...,5},ytick={5,10,15,20,25},
    y=0.3cm, xmax=5.4,ymax=26.9,ymin=0,xmin=0,
    enlargelimits=true,
    axis lines=middle,
    clip=false
    ]
\addplot+[color=red,fill=red!10!white,const plot, mark=none]
    coordinates {(0,2) (1,5) (2,10) (3,17) (4,26) (5,26)}\closedcycle;
\addplot+[color=green,fill=green!10!white,const plot, mark=none]
    coordinates {(0,1) (1,2) (2,5) (3,10) (4.0,17) (5,17)}\closedcycle;
\addplot[smooth, thick,domain=0:5]{1+x^2};
\end{axis}
\end{tikzpicture}
\begin{tikzpicture}
    \begin{axis}[
    xtick={0,...,5},ytick={5,10,15,20,25},
    y=0.3cm, xmax=5.4,ymax=26.9,ymin=0,
    axis lines=middle,
    clip=false,
        const plot,
        stack plots=y,
        area style]
    \addplot coordinates
        {(0,1) (1,2) (2,5) (3,10) (4.0,17) (5,17)}
        \closedcycle;
    \addplot coordinates
        {(0,1) (1,3) (2,5) (3,7) (4,9) (5,9)}
        \closedcycle;
    \end{axis}
    \begin{axis}[
        axis lines=none,
    y=0.3cm, xmax=5.4,ymax=26.9,ymin=0,
        ]
        \addplot[smooth,thick,color=black, domain=0:5]{1+x^2};
    \end{axis}
\end{tikzpicture}
\end{document}
7
  • @cmhughes I've seen both of those, but I'm looking for a solution that uses a largely pgfplots solution and has both upper and lower rectangles and for which I have total control over the possibly varying width of intervals. I have all this already with my own solution except for the hopefully minor issues I'm asking about. Oct 23, 2013 at 4:55
  • Maybe you could try gnuplot output for pgfplots.
    – Tawei
    Oct 23, 2013 at 6:00
  • Also related (basically duplicate): Lower and upper Riemann sums
    – Jake
    Oct 23, 2013 at 7:26
  • 1
    @Jake Fair call. I've done as you suggested. Your answer remains accepted though as that is where I got the answers to my two basic questions. Cheers Oct 24, 2013 at 8:29

5 Answers 5

13

You can use const plot mark right to get a piecewise constant plot for the right sum, and a ybar interval for the left sum. That way, you can just specify the same equation as for your line plot. Note that these aren't generally upper and lower sums, but rather right and left sums, but for monotonic functions like this one they're equivalent.

\documentclass[border=5mm]{standalone}

\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{pgfplots}

\pgfplotsset{compat=1.9}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
    xtick={0,...,5},ytick={5,10,15,20,25},
    y=0.3cm, xmax=5.4,ymax=26.9,ymin=0,xmin=0,
    enlargelimits=true,
    axis lines=middle,
    clip=false,
    domain=0:5,
    axis on top
    ]
\addplot [draw=red,fill=red!10,const plot mark right, samples=6]
    {1+x^2}\closedcycle;
\addplot [draw=green, fill=green!10, ybar interval, samples=6]
    {1+x^2}\closedcycle;
\addplot[smooth, thick,domain=0:5]{1+x^2};
\end{axis}
\end{tikzpicture}
\end{document}
6
  • Any simple way to get rid of the last unwanted green vertical overlap on the right had side? I've been messing around with this since I saw your solution and haven't found a simple way. Your comb idea basically solves my initial problem (1) but needs 1+(x-1)^2 to work properly and I just need to find the best way to avoid that last unwanted line. By hand, you can set the last two values equal to avoid it as I was doing initially. Cheers Oct 23, 2013 at 8:16
  • As to other solutions, I almost agree with the guy who said it's ultimately best to do most of the plot points by hand because I'm not after a high end package that blasts out perfect solutions no matter what you give it, it's just about preparing nice graphics for teaching purposes that are maintainable and you can vary a little for interest. I'm sure I can work out a way to do non monotonic examples. I've learnt a lot very quickly in the last couple of weeks with your help. Thanks Oct 23, 2013 at 8:18
  • @GeoffPointer: I've edited my answer.
    – Jake
    Oct 23, 2013 at 8:52
  • Now that is a nice succint little bit of code. I actually recall reading about ybar interval yesterday and the significance of only using the last plot point for the interval width escaped me at the time because I hadn't yet tried to do it with a general expression. BTW, the red one also works with ybar interval in combination with 1+(x+1)^2. Thanks heaps, this will do nicely Oct 23, 2013 at 11:14
  • First I get sidetracked by someone comments then I come up with an encapsulated solution. I've posted the solution to that parameter passing problem I had as a separate answer here seeing as it is relevant to this question. Cheers Oct 26, 2013 at 1:15
8

Here's a method that borrows from my answer to Tikz-PGF: Draw integral test plot

screenshot

% arara: pdflatex
% !arara: indent: {overwrite: true, trace: on}
\documentclass{standalone}

\usepackage{pgfplots}

% mid-point rule
\pgfplotsset{
    midpoint segments/.code={\pgfmathsetmacro\midpointsegments{#1}},
    midpoint segments=3,
    midpoint/.style args={#1:#2}{
        ybar interval,
        domain=#1+((#2-#1)/\midpointsegments)/2:#2+((#2-#1)/\midpointsegments)/2,
        samples=\midpointsegments+1,
        x filter/.code=\pgfmathparse{\pgfmathresult-((#2-#1)/\midpointsegments)/2}
    }
}

% right hand sums
\pgfplotsset{
    right segments/.code={\pgfmathsetmacro\rightsegments{#1}},
    right segments=3,
    right/.style args={#1:#2}{
        ybar interval,
        domain=#1+((#2-#1)/\rightsegments):#2+((#2-#1)/\rightsegments),
        samples=\rightsegments+1,
        x filter/.code=\pgfmathparse{\pgfmathresult-((#2-#1)/\rightsegments)}
    }
}

% left hand sums
\pgfplotsset{
    left segments/.code={\pgfmathsetmacro\leftsegments{#1}},
    left segments=3,
    left/.style args={#1:#2}{
        ybar interval,
        domain=#1:#2,
        samples=\leftsegments+1,
        x filter/.code=\pgfmathparse{\pgfmathresult}
    }
}



\begin{document}

\begin{tikzpicture}[/pgf/declare function={f=1+x^2;}]
    \begin{axis}[
            axis lines=middle,
            xtick={0,...,5},
            ytick={5,10,15,20,25},
            y=0.3cm, xmax=5.4,ymax=26.9,ymin=0,xmin=0,
            axis lines=middle,
            axis on top,
        ]
        \addplot [
            draw=red,fill=red!10,
            right segments=5,
            right=0:5,
        ] {f};
        \addplot [
            draw=green,fill=green!10,
            left segments=5,
            left=0:5,
        ] {f};
        \addplot [thick, domain=0:5] {f};
    \end{axis}
\end{tikzpicture}
\end{document}
1
  • These are handy routines and work well on my simple example but a solution for a more complicated plot requires some tweaking. See my answer. I will investigate your routines for my own education, thanks for sharing. Oct 24, 2013 at 8:39
6

A recommended solution with PSTricks. The fewer keystrokes you use, the more beautiful the code is, IMHO.

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pstricks-add}

%\def\f(#1){(#1+3)*(#1-1)*(#1-1.5)*(#1-4)/20+2}
\def\f(#1){(sqrt(3)*#1/2.5)^3-9*sqrt(3)*#1/2.5}
%\def\f(#1){#1*(#1-1)*(#1-3)/2+1}

\psset{algebraic,plotpoints=100,opacity=.5}

\begin{document}
\multido{\i=5+1}{10}{%
\begin{pspicture}(-5,-11)(6,12)
    \bgroup
        \psset{linecolor=gray,fillstyle=solid}
        \psStep[fillcolor=yellow](-4,4){\i}{\f(x)}
        \psStep[fillcolor=cyan,StepType=Riemann](-4,4){\i}{\f(x)}
    \egroup
    \psplot[linecolor=red]{-4}{4}{\f(x)}
    \psaxes{->}(0,0)(-5,-11)(5,11)[$x$,0][$y$,90]
\end{pspicture}}
\end{document}

enter image description here

It is the frozen animation.

enter image description here

7
  • Can you apply this to the example in my answer? f=((sqrt(3)*x/2.5)^3-9*(sqrt(3)*x/2.5) with domain=-4:4. Oct 24, 2013 at 9:15
  • When you say the fewer the keystrokes, there are an enormous number of keystrokes of code behind that pstricks solution. My solution may be more primitive but I've learnt a lot about tikz and pgfplots in the process which is currently a significant part of my aim. I don't currently use pstricks but my curiosity is piqued. I find that animation a bit hard on the eye, is there any chance you could freeze it to one column per unit? Oct 24, 2013 at 10:25
  • I'm not a knee jerk voter, I like to think things over before I decide if something has really helped me or is interesting. The pstricks solution has already been discussed. It tried this code and it takes ages to compile. There are also obvious colour inconsistencies across the range, a yellow strip above the axis in the -1 to 0 interval and an unwanted double line between the two regions below the 2 to 3 interval. I'm not sure the animation really helps either. Oct 24, 2013 at 10:55
  • If you have a look at each of the individual slides, many of them have glitches. This is one of the reasons I steer away from solutions like this. I'm basically a mathematician/musician who's interested in teaching first year uni maths and physics and who gets far too deeply sidetracked by computer programming in various guises. I mostly need to be writing my honours thesis in LaTeX, but I use it to prepare teaching materials and spend far too much time on it. Thanks for your input. Oct 24, 2013 at 11:09
  • @GeoffPointer: OK. It is your personal preference. I am still learning to be a good object oriented programmer who is taught not to expose the internal details to the consumers. However I also interested to dig more deeply on the encapsulated objects to know how they work behind the scene. Oct 24, 2013 at 12:03
5

Impelled by various lessons learnt here after posting this question, I went away and created my own package for visually representing various types of Riemann sum. I'm only just finding my way with this so if I need advice on how better to write a package, if anyone leaves a suggestion in a comment, rather than expanding this page further I can turn it into a separate question to be dealt with properly.

Update 8th Jan 2014: Since this answer was posted, I've not stopped learning and I've gradually refined my code and learnt how to package it in a .sty file. You can check it out here.

4
\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-func}

\def\f(x){ (sqrt(3)*x/2.5)^3-9*sqrt(3)*x/2.5 }
\psset{algebraic,plotpoints=100,yunit=0.5}    
\begin{document}
\begin{pspicture}(-5,-11)(6,12)
   \psStep[fillstyle=solid,fillcolor=red!10,linecolor=gray](-4,4){10}{\f(x)}
   \psStep[fillstyle=solid,fillcolor=green!10,linecolor=gray,StepType=Riemann](-4,4){10}{\f(x)}
    \psplot[linecolor=red,linewidth=1.5pt]{-4}{4}{\f(x)}
    \psaxes[Dy=2]{->}(0,0)(-5,-11)(5,11)[$x$,0][$y$,90]
\end{pspicture}
\end{document}

enter image description here

6
  • I tried this with 8 intervals and it worked well, but sidesteps the coloured boundary issue. What's the relationship between this and pstricks? The pstricks solution takes ages to compile, this was much quicker. Oct 24, 2013 at 10:41
  • Sorry, why do I get inconsistent color in my answer? It seems there are overlapped regions, is it a bug? Oct 24, 2013 at 11:05
  • Okay, I get it, they're basically both the same solution but Marienplatz's additional animation thing is why that one takes so long to compile. Oct 24, 2013 at 22:19
  • Looking closely at the output picture here with 10 rectangles between -4 and +4, there are several problems with it. The min and max are at exactly +2.5 and -2.5, but the two outer rectangles either side of each point are at slightly different heights. There's an unwanted line between -1 and 0 just above the x-axis. The colour relationship between upper and lower rectangles is reversed from one side of the y-axis to the other. Oct 24, 2013 at 22:29
  • @GeoffPointer: The x-value is 2.4 and not 2.5! 8/10=0.8 for the step. And the color is not reversed; it is the Riemann type
    – user2478
    Oct 25, 2013 at 6:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .