59
$\begingroup$

I would like to create a progress bar tool that allows me to see how my computations are going.

I found answers to this question on many sites, I even found a package for it ( http://www.physics.ohio-state.edu/~jeremy/mathematica/progress/#download ), but unfortunately, I have no knowledge whatsoever on programming and such, so I could not really understand the instructions for installing it properly (didn't know wether to use a notebook to create the package, go to the kernel, or something else?).

So I would really really appreciate if somebody could provide detailed step by step instructions for me to be able to get the progress bar going.

$\endgroup$
5
  • $\begingroup$ I use Windows 7 btw. $\endgroup$ Commented May 24, 2012 at 3:51
  • 2
    $\begingroup$ What I meant was if there was a way to get an add on for a permament progress bar for arbitrary computations. $\endgroup$ Commented May 24, 2012 at 5:14
  • 5
    $\begingroup$ Sorry you didn't understand my instructions. But note that I wrote that package for Mathematica 5.2. Mathematica 6 and later have built-in mechanisms (like ProgressIndicator, as pointed out by Brett) that are much better than, and don't have the overhead of, my package. I now use those; I don't use physics.ohio-state.edu/~jeremy/mathematica/progress/#download any more. $\endgroup$ Commented May 24, 2012 at 14:48
  • $\begingroup$ @EliyahUribe how could the kernel know when an arbitrary computation would finish? eg, consider this While[r = RandomReal[]; r < .999999, 1]; how long will it take? and there are simple computations which you really do need to carry out to find out how long they'll take $\endgroup$
    – acl
    Commented May 24, 2012 at 16:05
  • 1
    $\begingroup$ You can also monitor "estimated time remaining" till the end. Here is how: tiny.cc/c2v00w $\endgroup$ Commented Jul 30, 2013 at 6:56

3 Answers 3

68
$\begingroup$

I'd build something using Monitor and ProgressIndicator. For example:

Monitor[
 Table[Pause[0.1]; Prime[i], {i, 100}],
 Row[{ProgressIndicator[i, {1, 100}], i}, " "]
 ]

This shows a progress indicator while the calculation is underway

enter image description here

and then it disappears once the calculation has finished

enter image description here


If you look at Jeremy's file progress.m you linked to, you'll see that he defined functions like ProgressTable that are able to understand the iterator specifications. This is a decent approach, and I'm now going to do something similar in writing a ShowProgress function that understands basic Table iterators and has a generic fallback.

(* ShowProgress needs to hold it's arguments, otherwise it 
   tries to show progress for something that's already 
   completely done.*)
SetAttributes[ShowProgress, HoldAll];

(* Basic table syntaxes.  Excludes {i, {i1, i2, ...}} and multi-iterator forms *)
ShowProgress[Table[e_, {i_, max_}]] := 
   ShowProgress[Table[e, {i, 1, max, 1}]]
ShowProgress[Table[e_, {i_, min_, max_}]] := 
   ShowProgress[Table[e, {i, min, max, 1}]]
ShowProgress[Table[e_, {i_, min_, max_, step_}]] := 
   Monitor[
      Table[e, {i, min, max, step}],
      Row[{ProgressIndicator[i, {min, max}], i}, " "]
      ]

(* Fall-back: shows an indeterminate progress bar and elapsed time, 
   updating a few times per second *)
ShowProgress[a_] := 
   With[{progressStartTime = AbsoluteTime[]},
      Monitor[
        a, 
        Dynamic[Refresh[
           Row[{
              ProgressIndicator[Dynamic[Clock[]], Indeterminate], 
              AbsoluteTime[] - progressStartTime
              }, " "], 
           UpdateInterval -> 0.25]]
        ]]

Here are some examples of ShowProgress in use:

enter image description here enter image description here


I like this approach instead of the use of Progress... functions like in Jeremy's package because you don't need to change much of your code. You could hook ShowProgress in via $Pre to get automatically applied to everything. If you're willing to change code and use a special function when needed, then the Progress... functions are fine, although not too much different from ShowProgres[...].

The indeterminate progress bar with elapsed time is hopefully a little bit useful in the generic case where it can be difficult to know ahead of time how long a calculation will take. (Technically, there are times when it's unknown ahead of time whether something will finish at all.)

$\endgroup$
13
  • $\begingroup$ A guy earlier said something about the GUIkit(wich I already checked but could not get it to work) but I think he deleted it. The problem I find with using commands as Monitor and the ProgressIndicator is that they only work for dynamic looping variables (if not, I don't know how that works). What I am trying to get is something like an "add on", a progress bar that I can just fix into the Mathematica core that will pop on on every notebook I create, so that whenever I start a computation it automatically shows up without me needing to call it every single time. Is this even possible? Thanks $\endgroup$ Commented May 24, 2012 at 4:32
  • $\begingroup$ @EliyahUribe As I said earlier, if you have additional requirements, you should include all of it in your question before posting it. To answer your question, if you don't have a variable/estimate of how long each step/morsel-of-instructions-fed-to-the-kernel takes, then there is no way to know how it is progressing. It is highly unlikely that you'll find something that works like a blackbox for any computation. For instance, how should the progress bar behave in this case: (Label["a"];Goto["a"];1+1) $\endgroup$
    – rm -rf
    Commented May 24, 2012 at 4:40
  • $\begingroup$ @R.M I see. Well that's sad to hear, but I was kind of expecting it anyway...I guess I'll just have to indefinitely wait for Mathematica to compute things (like MatrixExp[] in most of the uses I give it, it takes really long). So, what does the package in the liknk I provided do then? And the progress bar created with the GUIKit package example? Thank you for your time and patience. $\endgroup$ Commented May 24, 2012 at 4:48
  • $\begingroup$ @EliyahUribe From a quick glance, the package you linked to provides a progress functionality (similar to what Brett outlined above) for some common Mathematica functions, all of which either take an iterator or operate on lists. For example, it adds the functionality to Do, Map, Nest, For, Fold, etc... this, plus some more eye candy (or not) like a window that looks and feels like MS Excel, etc. The GUIKit example allows you to create a widget that looks and behaves like a native OS application. $\endgroup$
    – rm -rf
    Commented May 24, 2012 at 4:54
  • $\begingroup$ @R.M Thank you, this has really enlightened me. Now I'll go and try and find out how to use the GUIKit example. $\endgroup$ Commented May 24, 2012 at 5:13
17
$\begingroup$

You can easily create your own version of a progress bar, and set it up with extras, like a scalebar:

progressBar[Dynamic[x_]] := DynamicModule[{texture},
   texture = 
    Table[ColorData["Rainbow", t] /. RGBColor -> List, {t, 0, 1, 
      1/100}];
   Graphics[{
     Texture@texture, 
     Polygon[{{0, 0}, {1, 0}, {1, 1}, {0, 1}}, 
      VertexTextureCoordinates -> {{0}, {0}, {1}, {1}}],
     [email protected], Dynamic@Polygon[{{0, x}, {1, x}, {1, 1}, {0, 1}}]
     },
    PlotRange -> {{0, 1}, {0, 1}}, PlotRangePadding -> 0,
    ImagePadding -> {{18, 18}, {5, 5}}, ImageSize -> {70, 300}, 
    AspectRatio -> 10,
    Frame -> True, FrameTicks -> {{True, All}, {None, None}}
    ]];

Let's test the indicator:

x = 0;
progressBar[Dynamic[x]]
Do[
 Pause[.01];(* simulate long calculation *)
 x = x + 0.01,
{100}];

enter image description here

$\endgroup$
5
$\begingroup$

A slight improvement I've needed based on Brett's initial answer.

The progress bar makes Unit tests in Wolfram Workbench fail as no frontend is available.

Here's a safe version of his code for this problem. Maybe could this issue be corrected in future versions ?

SetAttributes[safeMonitor,HoldAll];
safeMonitor[index_,startIndex_,endIndex_,label_,code_] /; $Notebooks :=
    Monitor[
        code
        ,
        Row[{ProgressIndicator[index, {startIndex, endIndex}], index},label]
    ];

safeMonitor[index_,startIndex_,endIndex_,label_,code_] := code;

(*example*)
safeMonitor[i, 1, 100, "Prime", Table[Pause[0.1]; Prime[i], {i, 100}]]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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