Message Boards Message Boards

0
|
6038 Views
|
6 Replies
|
1 Total Likes
View groups...
Share
Share this post:

How to Append Graphs and/or combine Plots?

Posted 10 years ago
Greetings.

Recently I have been working on a project for a class. Within the project I am attempting to display multiple circles constantly increasing in size as a For loop progresses. I have no problem increasing the size of the circles, nor displaying the circles, but the circles are constantly being over written by the next circle. I have been attempting to find a way to combine all of the circles into one graph, and also combine each circle into it's own graph (for individual use). This is the code I have written so far (there will also be an attatched copy).

 xSt[] = 0; (* x starting position *)
 ySt[] = 0; (*y starting position *)
 years = 0; (* The years that pass *)
 endTime = 100; (* Amount of years until the end of time *)
 probLife = 0; (* The probability that life will sprout up *)
 nLife = 0; (* Amount of Circles of Life; and designation number *)
 circleLife[] = 0; (* Circle of Life *)
 rMulti = 0 ; (* Growth multiplier *)
 rBase = 0; (* Base growth rate *)
rGrowth[] = 0; (* Rate of Growth for each CoL *)
orgGrowth[] =
  0; (* Used to keep track of original growth rate assigned to \
specific life form *)

ContourPlot[x y, {x, -1, 1}, {y, -1, 1},
PlotRange -> {{-100, 100}, {-100, 100}},
PlotLabel -> Dynamic["Year = " <> ToString[years]],
Epilog -> Dynamic[plot[[1]]]]

For[years = 1, years < endTime,
  probLife = RandomInteger[{1, 10}];
 
  (* The following If function checks if there are any circles of \
life and if there is, begins updating them,
  as if the life form is expanding radially *)
  If[nLife > 0,
   For[n = 1, n <= nLife,
    n++,
    rGrowth[n] = rGrowth[n] + orgGrowth[n];
    plot =
     ContourPlot[((a - xSt[n])^2 + (b - ySt[n])^2 ==
        rGrowth[n]^2), {a, -100 \[Pi], 100 \[Pi]}, {b, -100 \[Pi],
       100 \[Pi]},
      PlotRange -> {{-100, 100}, {-100, 100}}];
    (* Pause[0.1] *)](* End For n *)
   ]; (* End If nLife *)
 
  (* The following If function checks if the probability of life \
forming is true and if so creates a new form of life at a random \
point on the plot and the size and growth rate of that life form *)
  If[probLife == 1,
   {nLife = nLife + 1;
     xSt[nLife] = RandomReal[{-100, 100}];
     ySt[nLife] = RandomReal[{-100, 100}];
     rMulti = RandomReal[{.01, .1}];
     rBase = RandomReal[{1, 10}];
    
     rGrowth[nLife] = (rMulti rBase);
     orgGrowth[nLife] = (rMulti rBase);
     plot =
      ContourPlot[((a - xSt[nLife])^2 + (b - ySt[nLife])^2 ==
         rGrowth[nLife]^2), {a, -100 \[Pi],
        100 \[Pi]}, {b, -100 \[Pi], 100 \[Pi]},
       PlotRange -> {{-100, 100}, {-100, 100}}]};
   ]; probLife = 0;(* End If probLife *)
 
  (* Pause[0.1]; *)
  years++;
  ] ;(* End For years*)

Also, while attempting a variety of different methods and approaches, I receive this error message

"An improperly formatted option head (Graphics) was encountered while reading a Graphics. The head of the option must be Rule or RuleDelayed."

But I do not know exactly what it means, and my searches for an answer to this online has been fruitless.

Please help me Mathematica Community, you're my ony hope.
Attachments:
POSTED BY: Jeb Jennings
6 Replies
Posted 10 years ago
I have no idea what your Dynamic is doing, or even what it is supposed to be doing.
This is generating the frames for your movie, but not overlaying them.
If you Google for Mathematica movie then you can see some example code,
but I am not certain how to apply that directly to the code that you have written.
Attachments:
POSTED BY: Bill Simpson
Posted 10 years ago
If you look at the documentation for Reap you should see it returns a list with a couple of items in it. Item [[2,1]] is the "bag" of collected things that you put in there via Sow. The way I write code never needs anything else from Reap so I append that [[2,1]] without even thinking anymore.

The way that graphics were displayed changed in version 6. It used to be different from the way it is now and I have not put in the time to change the way I automatically think about assembling several different graphs onto a single sheet. So I'm not much use to you for generating movies.

It is a picky detail, but the way I was trained long ago. You seem to be using allPlots for two different things. The first time you seem to be using it as a label or title of just zero. Then you switch to having allPlots be a "bag" of images from Reap. I usually find I make fewer mistakes if each variable has a single purpose and a single kind of contents. It seems that for your first ContourPlot that allPlots will be zero and zero[[1]] isn't what I think you want.

You have also probably been taught another language before Mathematica because I see you using { and } to try to group statements. It is sort of possible to do that, but Mathematica isn't really doing what you think with that. Mathematica uses semicolons to sort of group items. I can't be certain that is what is breaking your code, but it worries me. You are also sort of using function definitions to save your plots. I can't tell at the moment if part of that is the reason that is causing your problem or not.

I'll fiddle with this a little more and see if I can find any serious problems. You can do the same. And hopefully you will learn even more in the process.
POSTED BY: Bill Simpson
Posted 10 years ago
Ah, I see now. That example cleared up some confusion that I was having, though I do not understand why the [2,1] is added at the end.

Also, you are correct that it does not resolve my "movie" issue. I have been able to create a multi variable list function "List," which allows me to save each circle and every growth event, but I am not able to show all of them happening at the same time (which I am sure that I can't with that multi variable list, but it was to be used later to analyze each circle and its respective growth pattern).

In regards to appending plots: Every time I attempt to append a plot, I receive errors such as "Graphics is not a Graphics primitive or directive." Or a variety of other errors dealing with graphics. I assume that if I can append a plot during my growth counters/building, that I will be able to display a plot that shows all of the circles expanding at once (not actually, but close to it).

When this is done, the years are suppose to jump up to a few million, and the plot is going to be expanded to a few hundred thousand^2.

The attachted file shows updates which bring me ever so closer to something usable, but why does Dynamic not accept the allPlots function? Why does allPlots not display with the For loops when called upon?

Honestly, I appreciate all of your help. This is helping me learn a lot, and is kind of fun.
Attachments:
POSTED BY: Jeb Jennings
Posted 10 years ago
Reap and Sow aren't quite behaving the way you think they are.

See if this example helps.

And this still doesn't address your "movie" goal.
Attachments:
POSTED BY: Bill Simpson
Posted 10 years ago
Thank you Bill Simpson, I highly appreciate your assistance. It has helped me to understand more about Mathematica and also learn more through exploration, but

I tried a similar code to yours (and a variety of variations), and I am not producing the same result that you mention. I added a For loop into the Reap function, as you did, but my results do not produce a single graph over laid with all of the other graphs.

Also, I am attempting to make a movie, but also save each expanding circle as its own movie to be viewable independantly. I would also like to display the ultimate finished product (all of the circle outcomes) displayed at once. I like to think that I would be able to achieve this if I am able to get the Reap function you mentioned working correctly.

Thank you for introducing &DisplayFunction.
Attachments:
POSTED BY: Jeb Jennings
Posted 10 years ago
Inside a For loop each Plot is roughly saying "I don't know what you have done before and I really don't care, forget that, give me a new blank sheet to draw a plot on."

I can't really address what looks like your desire to create a movie with each new plot added as another frame, that would be more complicated.

Perhaps you can use this idea and see if it will get you at least part of what you need.

If you use
 allplots=Reap[
    For[
       plot=ContourPlot[ ];
       Sow[plot]
       ...
       plot=ContourPlot[ ];
       Sow[plot]
       ...
    ]
][[2,1]];
Show[allplots]
then each ContourPlot is still going to overwrite the previous one and you won't get your movie.

BUT when the movie finishes that last Show is going to display all the frames of your movie overlaid as a single plot.
Roughly, Reap is creating a bag and every time you have a Sow inside it you will add one more item to the bag.
When you finally finish all the code inside the Reap then it will give you the bag with the contents.
In your case the bag will be filled with individual plots and you can Show a list of superimposed plots.

I just tried this and I can see all your plots overlaid on a single sheet at the end.

You could, with more care and work, create your own empty list of plots, append each new plot to the end
of the list, Show that list after you add each new plot and attempt to create your movie. This might
give you enough of a hint to be able to do that if that is what you need to do.
You can also use $DisplayFunction to disable the display of the individual frames and then turn on
the display function for the accumulated list of plots. Again, this is more complicated for you to do.
POSTED BY: Bill Simpson
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract