I need help. I have many variables, that I use in my Graphics[] command, that are dependent of one variable (H in my example). I want to manipulate my graphic so that by changing value of H graphic changes accordingly. But it is not as easy as I've thought.
If you have any idea on how to acomplish this, I would be grateful.
(*This variables are dependent on H that I want to change in
manipulate*)
R = 10;
\[Alpha] = ArcSin[H/R];
p = H/Tan[\[Alpha]];
n = 1.5;
\[Beta] = ArcSin[n Sin[\[Alpha]]];
\[Theta] = \[Beta] - \[Alpha];
l = H/Tan[\[Theta]];
(*This is the graphic I want to make manipulated*)
Graphics[{(*Incident ray*)Line[{{-2, H}, {p, H}}],(*Prism*)
Circle[{0, 0}, R, {0, Pi/2}],
Line[{{0, 0}, {0, 10}}],(*Refracted ray*)
Line[{{p, H}, {p + l, 0}}],(*Surface*)
Line[{{0, 0}, {p + l + 10, 0}}]}]
Here's one of my solutions but it's really messy. What I did is just manually pluged in those values. Is there any more appropriate way to acomplish this:
R = 10;
n = 1.5;
Manipulate[
Graphics[{(*Incident ray*)
Line[{{-2, H}, {H/Tan[ArcSin[H/10]], H}}],(*Prism*)
Circle[{0, 0}, R, {0, Pi/2}],
Line[{{0, 0}, {0, 10}}],(*Refracted ray*)
Line[{{H/Tan[ArcSin[H/10]],
H}, {H/Tan[ArcSin[H/10]] +
H/Tan[ArcSin[n Sin[ArcSin[H/10]]] - ArcSin[H/10]],
0}}],(*Surface*)
Line[{{0,
0}, {H/Tan[ArcSin[H/10]] +
H/Tan[ArcSin[n Sin[ArcSin[H/10]]] - ArcSin[H/10]] + 10,
0}}]}], {H, 0.0001, 10, Appearance -> "Labeled"}]
And also how to make my graphic not to change it's size constantly. I want prism to have fixed size and incident ray to change its position (as it happens when H gets > 6.66 in my example above / this solution).
The question is maybe confusing, but if you try it in Mathematica, you'll see what I want. Thank you for any suggestions.
I think your solution is not bad in general, Mark already noticed in his reply. I loved simplicity of Mark's solution too. Just for the sake of experiment I share my ideas too.
1) It is always a good thing to localize your variables for a specific Manipulate, so their values do not leak and interfere with other dynamic content. It matters if you have additional computation in your notebook - they may start resetting each other.
2) In this particular case if you try to get read of extra variables plugging expressions one into each other your equations became complicated and it is hard to see why they would fail some times. A bit of algebra with help of functions TrigExpand and FullSimplify may help to clarify that your variable H has limitations depending on refraction index value n (see below).
3) If we are aware of point (2) we can make variable n dynamic too and link the value H to n (resetting upper bound of H) right in the controls definition, so always it should be H<10/n . If[..] is also necessary so the controls will not “pink”.
4) If your formulas would depend on R we could also make R dynamic. But I do not have this information, so I localized R via concept of a “dummy“ control (ControlType -> None) – which is quite useful concept for Manipulate.
5) Use PlotRange and ImageSize to stop jiggling of graphics
6) Make it beautiful ;-)
These points would be important if you’d like, for example, to submit a Demonstration to the Wolfram Demonstration Project. If you are just playing around – I think yours and Mark’s solutions are very good.
Thanks,
Vitaliy
Manipulate[If[H >= 10/n, H = 10/n - .0001]; Graphics[{
{Red, Thick, Line[{{-2, H}, {Sqrt[100 - H^2], H}}]},
{Blue, Opacity[.5], Disk[{0, 0}, R, {0, Pi/2}]},
{Red, Thick, Line[{{Sqrt[100 - H^2], H},
{(100 n)/(Sqrt[100 - H^2] n - Sqrt[100 - H^2 n^2]), 0}}]}},
Axes -> True, PlotRange -> {{0, 30}, {0, 10}},
ImageSize -> {600, 200}], {{R, 10}, ControlType -> None},
{{n, 1.5, "Refraction"}, 1.001, 2, Appearance -> "Labeled"},
{{H, 3, "Length"}, 0.0001, 10/n - .0001, Appearance -> "Labeled"}]
I think your first batch of code looks fine and is easy to place into a Manipulate. I would recommend use of the PlotRange option in Graphics.
R = 10;
n = 1.5;
Manipulate[
\[Alpha] = ArcSin[H/R];
p = H/Tan[\[Alpha]];
\[Beta] = ArcSin[n Sin[\[Alpha]]];
\[Theta] = \[Beta] - \[Alpha];
l = H/Tan[\[Theta]];
Graphics[{
Line[{{-2, H}, {p, H}}],(*Prism*)
Circle[{0, 0}, R, {0, Pi/2}],
Line[{{0, 0}, {0, 10}}],(*Refracted ray*)
Line[{{p, H}, {p + l, 0}}],(*Surface*)
Line[{{0, 0}, {p + l + 10, 0}}]},
PlotRange -> {{-1,33},{-1,11}}],
{H,0.0001,6,Appearance->"Labeled"}]
Related
I've been learning Sow/Reap. They are cool constructs. But I need help to see if I can use them to do what I will explain below.
What I'd like to do is: Plot the solution of NDSolve as it runs. I was thinking I can use Sow[] to collect the solution (x,y[x]) as NDSolve runs using EvaluationMonitor. But I do not want to wait to the end, Reap it and then plot the solution, but wanted to do it as it is running.
I'll show the basic setup example
max = 30;
sol1 = y /.
First#NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1},
y, {x, 0, max}];
Plot[sol1[x], {x, 0, max}, PlotRange -> All, AxesLabel -> {"x", "y[x]"}]
Using Reap/Sow, one can collect the data points, and plot the solution at the end like this
sol = Reap[
First#NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1},
y, {x, 0, max}, EvaluationMonitor :> Sow[{x, y[x]}]]][[2, 1]];
ListPlot[sol, AxesLabel -> {"x", "y[x]"}]
Ok, so far so good. But what I want is to access the partially being build list, as it accumulates by Sow and plot the solution. The only setup I know how do this is to have Dynamic ListPlot that refreshes when its data changes. But I do not know how to use Sow to move the partially build solution to this data so that ListPlot update.
I'll show how I do it without Sow, but you see, I am using AppenedTo[] in the following:
ClearAll[x, y, lst];
max = 30;
lst = {{0, 0}};
Dynamic[ListPlot[lst, Joined -> False, PlotRange -> {{0, max}, All},
AxesLabel -> {"x", "y[x]"}]]
NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, y, {x, 0, max},
EvaluationMonitor :> {AppendTo[lst, {x, y[x]}]; Pause[0.01]}]
I was thinking of a way to access the partially build list by Sow and just use that to refresh the plot, on the assumption that might be more efficient than AppendTo[]
I can't just do this:
ClearAll[x, y, lst];
max = 30;
lst = {{0, 0}};
Dynamic[ListPlot[lst, Joined -> False, PlotRange -> All]]
NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, y, {x, 0, max},
EvaluationMonitor :> {lst = Reap[Sow[{x, y[x]}] ][[2, 1]]; Pause[0.01]}]
Since it now Sow one point, and Reap it, so I am just plotting one point at a time. The same as if I just did:
NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, y, {x, 0, max},
EvaluationMonitor :> {lst = Sow[{x, y[x]}]; Pause[0.01]}]
my question is, how to use Sow/Reap in the above, to avoid me having manage the lst by the use of AppendTo in this case. (or by pre-allocation using Table, but then I would not know the size to allocate) Since I assume that may be Sow/Reap would be more efficient?
ps. What would be nice, if Reap had an option to tell it to Reap what has been accumulated by Sow, but do not remove it from what has been Sow'ed so far. Like a passive Reap sort of. Well, just a thought.
thanks
Update: 8:30 am
Thanks for the answers and comments. I just wanted to say, that the main goal of asking this was just to see if there is a way to access part of the data while being Sowed. I need to look more at Bag, I have not used that before.
Btw, The example shown above, was just to give a context to where such a need might appear. If I wanted to simulate the solution in this specific case, I do not even have to do it as I did, I could obtain the solution data first, then, afterwords, animate it.
Hence no need to even worry about allocation of a buffer myself, or use AppenedTo. But there could many other cases where it will be easier to access the data as it is being accumulated by Sow. This example is just what I had at the moment.
To do this specific example more directly, one can simply used Animate[], afterwords, like this:
Remove["Global`*"];
max = 30;
sol = Reap[
First#NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1},
y, {x, 0, max}, EvaluationMonitor :> Sow[{x, y[x]}]]][[2, 1]];
Animate[ListPlot[sol[[1 ;; idx]], Joined -> False,
PlotRange -> {{0, max}, All}, AxesLabel -> {"x", "y[x]"}], {idx, 1,
Length[sol], 1}]
Or, even make a home grown animate, like this
Remove["Global`*"];
max = 30;
sol = Reap[
First#NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1},
y, {x, 0, max}, EvaluationMonitor :> Sow[{x, y[x]}]]][[2, 1]];
idx = 1;
Dynamic[idx];
Dynamic[ListPlot[sol[[1 ;; idx]], Joined -> False,
PlotRange -> {{0, max}, All}, AxesLabel -> {"x", "y[x]"}]]
Do[++idx; Pause[0.01], {i, 1, Length[sol] - 1}]
Small follow up question: Can one depend on using Internal``Bag now? Since it is in Internal context, will there be a chance it might be removed/changed/etc... in the future, breaking some code? I seems to remember reading somewhere that this is not likely, but I do not feel comfortable using something in Internal Context. If it is Ok for us to use it, why is it in Internal context then?
(so many things to lean in Mathematica, so little time)
Thanks,
Experimentation shows that both Internal`Bag and linked lists are slower than using AppendTo. After considering this I recalled what Sasha told me, which is that list (array) creation is what takes time.
Therefore, neither method above, nor a Sow/Reap in which the result is collected as a list at each step is going to be more efficient (in fact, less) than AppendTo.
I believe that only array pre-allocation can be faster among the native Mathematica constructs.
Old answer below for reference:
I believe this is the place for Internal`Bag, Internal`StuffBag, and Internal`BagPart.
I had to resort to a clumsy double variable method because the Bag does not seem to update inside Dynamic the way I expected.
ClearAll[x, y, lst];
max = 30;
bag = Internal`Bag[];
lst = {{}};
Dynamic#ListPlot[lst, Joined -> False, PlotRange -> All]
NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, y, {x, 0, max},
EvaluationMonitor :> {Internal`StuffBag[bag, {x, y[x]}];
lst = Internal`BagPart[bag, All];
Pause[0.01]}
]
I have already checked all the examples and settings in the Mathematica documentation center, but couldn't find any example on how to choose the numbers that will be shown on the axes.
How do I change plot axis numbering like 2,4,6,.. to PI,2PI,3PI,...?
Howard has already given the correct answer in the case where you want the labels Pi, 2 Pi etc to be at the values Pi, 2 Pi etc.
Sometimes you might want to use substitute tick labels at particular values, without rescaling data.
One of the other examples in the documentation shows how:
Plot[Sin[x], {x, 0, 10},
Ticks -> {{{Pi, 180 \[Degree]}, {2 Pi, 360 \[Degree]}, {3 Pi,
540 \[Degree]}}, {-1, 1}}]
I have a suite of small custom functions for formatting Ticks the way I want them. This is probably too much information if you are just starting out, but it is worth knowing that you can use any number format and substitute anything into your ticks if desired.
myTickGrid[min_, max_, seg_, units_String, len_?NumericQ,
opts : OptionsPattern[]] :=
With[{adj = OptionValue[UnitLabelShift], bls = OptionValue[BottomLabelShift]},
Table[{i,
If[i == max,
DisplayForm[AdjustmentBox[Style[units, LineSpacing -> {0, 12}],
BoxBaselineShift -> If[StringCount[units, "\n"] > 0, adj + 2, adj]]],
If[i == min,
DisplayForm#AdjustmentBox[Switch[i, _Integer,
NumberForm[i, DigitBlock -> 3,
NumberSeparator -> "\[ThinSpace]"], _, N[i]],
BoxBaselineShift -> bls],
Switch[i, _Integer, NumberForm[i, DigitBlock -> 3,
NumberSeparator -> "\[ThinSpace]"], _, N[i]]]], {len, 0}}, {i,
If[Head[seg] === List, Union[{min, max}, seg], Range[min, max, seg]]}]]
And setting:
Options[myTickGrid] = {UnitLabelShift -> 1.3, BottomLabelShift -> 0}
SetOptions[myTickGrid, UnitLabelShift -> 1.3, BottomLabelShift -> 0]
Example:
Plot[Erfc[x], {x, -2, 2}, Frame -> True,
FrameTicks -> {myTickGrid[-2, 2, 1, "x", 0.02, UnitLabelShift -> 0],
myTickGrid[0, 2, {0.25, .5, 1, 1.8}, "Erfc(x)", 0.02]}]
You can find an example here:
Ticks -> {{Pi, 2 Pi, 3 Pi}, {-1, 0, 1}}
Ticks also accepts a function, which will save you the trouble of listing the points manually or having to change the max value each time. Here's an example:
xTickFunc[min_, max_] :=
Table[{i, i, 0.02}, {i, Ceiling[min/Pi] Pi, Floor[max/Pi] Pi, Pi}]
Plot[Sinc[x], {x, -5 Pi, 5 Pi}, Ticks -> {xTickFunc, Automatic},
PlotRange -> All]
If you want more flexibility in customizing your ticks, you might want to look into LevelScheme.
How can I write the code for a function (complex contour) similar to this in Mathematica:
I am not exactly sure what c is, but I assumed it was a number between 0 and 1 meaning the height of the incoming straight line. So maybe somehting like this would suit your needs?
c = 0.7;
t0 = ArcSin[c];
PolarPlot[If[Abs[t] < t0, Abs[Sin[t0]/Sin[t]], 1], {t, -\[Pi], \[Pi]}]
The most direct way is to use graphics primatives
(although I think I prefer Felix's PolarPlot solution)
With[{q = Pi/6},
Graphics[{Circle[{0, 0}, 1, {q, 2 Pi - q}],
Arrowheads[{{.05, .8}}],
Arrow[{{Cos[q] + 2, Sin[q]}, {Cos[q], Sin[q]}}],
Arrow[{{Cos[q], Sin[-q]}, {Cos[q] + 2, Sin[-q]}}],
FontSize -> Medium, Text["\[ScriptCapitalC]", {2, Sin[q]}, {0, -2}]},
Axes -> True, PlotRange -> {{-4, 6}, {-4, 4}}]]
I guess if you want the actual function for contour, then maybe something like
contour[t_, t0_: (5 Pi/6)] := Piecewise[{
{Exp[I (t + Pi)], -t0 < t < t0},
{t - t0 + Exp[I (t0 + Pi)], t >= t0},
{-t - t0 + Exp[-I (t0 + Pi)], t <= -t0}}]
ParametricPlot[Through[{Re, Im}[contour[t]]], {t, -8, 8}, PlotPoints -> 30]
And to add arrows to this plot, I guess you'd have to add them in manually (using Epilog or the drawing tools) or use one of the packages that modifies the built-in plots.
I am looking to plot something like the whispering gallery modes -- a 2D cylindrically symmetric plot in polar coordinates. Something like this:
I found the following code snippet in Trott's symbolics guidebook. Tried running it on a very small data set; it ate 4 GB of memory and hosed my kernel:
(* add points to get smooth curves *)
addPoints[lp_][points_, \[Delta]\[CurlyEpsilon]_] :=
Module[{n, l}, Join ## (Function[pair,
If[(* additional points needed? *)
(l = Sqrt[#. #]&[Subtract ## pair]) < \[Delta]\[CurlyEpsilon], pair,
n = Floor[l/\[Delta]\[CurlyEpsilon]] + 1;
Table[# + i/n (#2 - #1), {i, 0, n - 1}]& ## pair]] /#
Partition[If[lp === Polygon,
Append[#, First[#]], #]&[points], 2, 1])]
(* Make the plot circular *)
With[{\[Delta]\[CurlyEpsilon] = 0.1, R = 10},
Show[{gr /. (lp : (Polygon | Line))[l_] :>
lp[{#2 Cos[#1], #2 Sin[#1]} & ###(* add points *)
addPoints[lp][l, \[Delta]\[CurlyEpsilon]]],
Graphics[{Thickness[0.01], GrayLevel[0], Circle[{0, 0}, R]}]},
DisplayFunction -> $DisplayFunction, Frame -> False]]
Here, gr is a rectangular 2D ListContourPlot, generated using something like this (for example):
data = With[{eth = 2, er = 2, wc = 1, m = 4},
Table[Re[
BesselJ[(Sqrt[eth] m)/Sqrt[er], Sqrt[eth] r wc] Exp[
I m phi]], {r, 0, 10, .2}, {phi, 0, 2 Pi, 0.1}]];
gr = ListContourPlot[data, Contours -> 50, ContourLines -> False,
DataRange -> {{0, 2 Pi}, {0, 10}}, DisplayFunction -> Identity,
ContourStyle -> {Thickness[0.002]}, PlotRange -> All,
ColorFunctionScaling -> False]
Is there a straightforward way to do cylindrical plots like this?.. I find it hard to believe that I would have to turn to Matlab for my curvilinear coordinate needs :)
Previous snippets deleted, since this is clearly the best answer I came up with:
With[{eth = 2, er = 2, wc = 1, m = 4},
ContourPlot[
Re[BesselJ[(Sqrt[eth] m)/Sqrt[er], Sqrt[eth] r wc] Exp[I phi m]]/.
{r ->Norm[{x, y}], phi ->ArcTan[x, y]},
{x, -10, 10}, {y, -10, 10},
Contours -> 50, ContourLines -> False,
RegionFunction -> (#1^2 + #2^2 < 100 &),
ColorFunction -> "SunsetColors"
]
]
Edit
Replacing ContourPlot by Plot3D and removing the unsupported options you get:
This is a relatively straightforward problem. The key is that if you can parametrize it, you can plot it. According to the documentation both ListContourPlot and ListDensityPlot accept data in two forms: an array of height values or a list of coordinates plus function value ({{x, y, f} ..}). The second form is easier to deal with, such that even if your data is in the first form, we'll transform it into the second form.
Simply, to transform data of the form {{r, t, f} ..} into data of the form {{x, y, f} ..} you doN[{#[[1]] Cos[ #[[2]] ], #[[1]] Sin[ #[[2]] ], #[[3]]}]& /# data, when applied to data taken from BesselJ[1, r/2] Cos[3 t] you get
What about when you just have an array of data, like this guy? In that case, you have a 2D array where each point in the array has known location, and in order to plot it, you have to turn it into the second form. I'm partial to MapIndexed, but there are other ways of doing it. Let's say your data is stored in an array where the rows correspond to the radial coordinate and the columns are the angular coordinate. Then to transform it, I'd use
R = 0.01; (*radial increment*)
T = 0.05 Pi; (*angular increment*)
xformed = MapIndexed[
With[{r = #2[[1]]*R, t = #2[[1]]*t, f = #1},
{r Cos[t], r Sin[t], f}]&, data, {2}]//Flatten[#,1]&
which gives the same result.
If you have an analytic solution, then you need to transform it to Cartesian coordinates, like above, but you use replacement rules, instead. For instance,
ContourPlot[ Evaluate[
BesselJ[1, r/2]*Cos[3 t ] /. {r -> Sqrt[x^2 + y^2], t -> ArcTan[x, y]}],
{x, -5, 5}, {y, -5, 5}, PlotPoints -> 50,
ColorFunction -> ColorData["DarkRainbow"], Contours -> 25]
gives
Two things to note: 1) Evaluate is needed to ensure that the replacement is performed correctly, and 2) ArcTan[x, y] takes into account the quadrant that the point {x,y} is found in.
When plotting a function using Plot, I would like to obtain the set of data points plotted by the Plot command.
For instance, how can I obtain the list of points {t,f} Plot uses in the following simple example?
f = Sin[t]
Plot[f, {t, 0, 10}]
I tried using a method of appending values to a list, shown on page 4 of Numerical1.ps (Numerical Computation in Mathematica) by Jerry B. Keiper, http://library.wolfram.com/infocenter/Conferences/4687/ as follows:
f = Sin[t]
flist={}
Plot[f, {t, 0, 10}, AppendTo[flist,{t,f[t]}]]
but generate error messages no matter what I try.
Any suggestions would be greatly appreciated.
f = Sin[t];
plot = Plot[f, {t, 0, 10}]
One way to extract points is as follows:
points = Cases[
Cases[InputForm[plot], Line[___],
Infinity], {_?NumericQ, _?NumericQ}, Infinity];
ListPlot to 'take a look'
ListPlot[points]
giving the following:
EDIT
Brett Champion has pointed out that InputForm is superfluous.
ListPlot#Cases[
Cases[plot, Line[___], Infinity], {_?NumericQ, _?NumericQ},
Infinity]
will work.
It is also possible to paste in the plot graphic, and this is sometimes useful. If,say, I create a ListPlot of external data and then mislay the data file (so that I only have access to the generated graphic), I may regenerate the data by selecting the graphic cell bracket,copy and paste:
ListPlot#Transpose[{Range[10], 4 Range[10]}]
points = Cases[
Cases[** Paste_Grphic _Here **, Point[___],
Infinity], {_?NumericQ, _?NumericQ}, Infinity]
Edit 2.
I should also have cross-referenced and acknowledged this very nice answer by Yaroslav Bulatov.
Edit 3
Brett Champion has not only pointed out that FullForm is superfluous, but that in cases where a GraphicsComplex is generated, applying Normal will convert the complex into primitives. This can be very useful.
For example:
lp = ListPlot[Transpose[{Range[10], Range[10]}],
Filling -> Bottom]; Cases[
Cases[Normal#lp, Point[___],
Infinity], {_?NumericQ, _?NumericQ}, Infinity]
gives (correctly)
{{1., 1.}, {2., 2.}, {3., 3.}, {4., 4.}, {5., 5.}, {6., 6.}, {7.,
7.}, {8., 8.}, {9., 9.}, {10., 10.}}
Thanks to Brett Champion.
Finally, a neater way of using the general approach given in this answer, which I found here
The OP problem, in terms of a ListPlot, may be obtained as follows:
ListPlot#Cases[g, x_Line :> First#x, Infinity]
Edit 4
Even simpler
ListPlot#Cases[plot, Line[{x__}] -> x, Infinity]
or
ListPlot#Cases[** Paste_Grphic _Here **, Line[{x__}] -> x, Infinity]
or
ListPlot#plot[[1, 1, 3, 2, 1]]
This evaluates to True
plot[[1, 1, 3, 2, 1]] == Cases[plot, Line[{x__}] -> x, Infinity]
One way is to use EvaluationMonitor option with Reap and Sow, for example
In[4]:=
(points = Reap[Plot[Sin[x],{x,0,4Pi},EvaluationMonitor:>Sow[{x,Sin[x]}]]][[2,1]])//Short
Out[4]//Short= {{2.56457*10^-7,2.56457*10^-7},<<699>>,{12.5621,-<<21>>}}
In addition to the methods mentioned in Leonid's answer and my follow-up comment, to track plotting progress of slow functions in real time to see what's happening you could do the following (using the example of this recent question):
(* CPU intensive function *)
LogNormalStableCDF[{alpha_, beta_, gamma_, sigma_, delta_}, x_] :=
Block[{u},
NExpectation[
CDF[StableDistribution[alpha, beta, gamma, sigma], (x - delta)/u],
u \[Distributed] LogNormalDistribution[Log[gamma], sigma]]]
(* real time tracking of plot process *)
res = {};
ListLinePlot[res // Sort, Mesh -> All] // Dynamic
Plot[(AppendTo[res, {x, #}]; #) &#
LogNormalStableCDF[{1.5, 1, 1, 0.5, 1}, x], {x, -4, 6},
PlotRange -> All, PlotPoints -> 10, MaxRecursion -> 4]
etc.
Here is a very efficient way to get all the data points:
{plot, {points}} = Reap # Plot[Last#Sow#{x, Sin[x]}, {x, 0, 4 Pi}]
Based on the answer of Sjoerd C. de Vries, I've now written the following code which automates a plot preview (tested on Mathematica 8):
pairs[x_, y_List]:={x, #}& /# y
pairs[x_, y_]:={x, y}
condtranspose[x:{{_List ..}..}]:=Transpose # x
condtranspose[x_]:=x
Protect[SaveData]
MonitorPlot[f_, range_, options: OptionsPattern[]]:=
Module[{data={}, plot},
Module[{tmp=#},
If[FilterRules[{options},SaveData]!={},
ReleaseHold[Hold[SaveData=condtranspose[data]]/.FilterRules[{options},SaveData]];tmp]]&#
Monitor[Plot[(data=Union[data, {pairs[range[[1]], #]}]; #)& # f, range,
Evaluate[FilterRules[{options}, Options[Plot]]]],
plot=ListLinePlot[condtranspose[data], Mesh->All,
FilterRules[{options}, Options[ListLinePlot]]];
Show[plot, Module[{yrange=Options[plot, PlotRange][[1,2,2]]},
Graphics[Line[{{range[[1]], yrange[[1]]}, {range[[1]], yrange[[2]]}}]]]]]]
SetAttributes[MonitorPlot, HoldAll]
In addition to showing the progress of the plot, it also marks the x position where it currently calculates.
The main problem is that for multiple plots, Mathematica applies the same plot style for all curves in the final plot (interestingly, it doesn't on the temporary plots).
To get the data produced into the variable dest, use the option SaveData:>dest
Just another way, possibly implementation dependent:
ListPlot#Flatten[
Plot[Tan#t, {t, 0, 10}] /. Graphics[{{___, {_, y__}}}, ___] -> {y} /. Line -> List
, 2]
Just look into structure of plot (for different type of plots there would be a little bit different structure) and use something like that:
plt = Plot[Sin[x], {x, 0, 1}];
lstpoint = plt[[1, 1, 3, 2, 1]];