# How to speed up multi-curve plotting?

The following example is a very simplified version of the problem I'm working with, though I hope it still captures the essentials. First, the definitions:

sigmoid[s_, a_][x_] := (a (-s + x))/Sqrt[1 + a^2 (s - x)^2];

plots[params_] := Module[{fns},
fns = sigmoid @@ # & /@ params;
Plot[#[x] & /@ fns, {x, -20, 20}, ImageSize -> Small]];


The plots function produces a plot containing as many sigmoid curves as there are parameter sets in the list params. E.g., with 5 parameter sets (differing only in the first parameter):

plots[{{-10, 1}, {-5, 1}, {0, 1}, {5, 1}, {10, 1}}]


plots produces

More typically, however, I need to run plots with an argument consisting of ~100 sets of parameters, and I'm finding it to take considerably longer than I had expected. (Maybe I've gotten spoiled!)

For example, running

plots[{#, 1} & /@ Array[# &, 100, {-15, 15}]]


takes ~40s on my desktop. Does this sound right?

Currently I am in the process of producing several figures each consisting of a grid containing ~100 plots of comparable complexity (i.e. ~100 curves/plot), so I need to find ways to significantly speed this up. Any suggestions would be appreciated.

NB: The details of the sigmoid function should not be an important aspect of the proposed optimization, since I chose this function for this example only because it is significantly simpler than the function that I am actually working with. (For one thing, the latter is parametrized by three rather than two numbers. Nevertheless, it produces s-shaped curves looking very similar those produced by sigmoid.)

-
You might find a non-trivial speed increase if you switch to ListLinePlot. A fair bit of time is spent in Plot trying to "inspect" your function and determine how to sample it adaptively. This is helpful when it comes to discontinuities/exclusions, etc. However, if your function is smooth, you can just choose a fixed sampling grid and use that for all values of your parameter. Also, with 100 values of the parameter/plot, you might also want to reconsider if Plot is indeed what you want to use... perhaps a 2D plot (ArrayPlot) might be more useful. –  rm -rf Sep 30 '13 at 18:38
Thanks! Switching to ListLinePlot made a huge difference. Please post your comment so that I can accept it. –  kjo Sep 30 '13 at 20:14

You might find a non-trivial speed increase if you switch to ListLinePlot. A fair bit of time is spent in Plot trying to "inspect" your function and determine how to sample it adaptively — for each curve being plotted. This is helpful when it comes to discontinuities/exclusions, etc., but starts to get out of hand when you have a lot of curves to plot.

If your function is smooth, you can just choose a fixed sampling grid and use that for all values of your parameter. For example, reformulating your plots function as:

plotsL[params_, {xmin_, xmax_, dx_}] := Module[{fns, xgrid},
fns = sigmoid @@ # & /@ params;
xgrid = Range[xmin, xmax, dx];
ListLinePlot[#[xgrid] & /@ fns, ImageSize -> Small, DataRange -> {xmin, xmax}]
];

plotsL[{{-10, 1}, {-5, 1}, {0, 1}, {5, 1}, {10, 1}}, {-20, 20, 0.05}]


This should be much faster than using just Plot by itself.

-