MathGroup Archive 2012

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: RE: creating a graphic in a text cell

  • To: mathgroup at smc.vnet.net
  • Subject: [mg128210] Re: RE: creating a graphic in a text cell
  • From: Alexei Boulbitch <Alexei.Boulbitch at iee.lu>
  • Date: Tue, 25 Sep 2012 04:37:55 -0400 (EDT)
  • Delivered-to: l-mathgroup@mail-archive0.wolfram.com
  • Delivered-to: l-mathgroup@wolfram.com
  • Delivered-to: mathgroup-newout@smc.vnet.net
  • Delivered-to: mathgroup-newsend@smc.vnet.net
  • References: <5F5696D639DA7D4C842D85A250023D8710D4234D@DB3PRD0710MB393.eurprd07.prod.outlook.com>

Dear Dushan, dear James, dear Syd, dear Community members,

I received several questions concerning my "very hi-fi" simplification method for drawing. Of course, it is nothing sophisticated in reality. There are only few simple advises as follows.

1. The main trick is that while the image is not ready I am used to envelope the whole code with Manipulate statement. I do it from the very beginning placing there dummy parameters. Later, when looking for suitable coordinate or angles (that I cannot calculate within a second in mind) I use it to fast get the numbers. To give an example I am writing the code below which is my previous drawing. Now, however, the coordinates of the second brick (brick2) are not fixed and should be worked out in the course of manipulation.

(* The manipulate statement begins *)

Manipulate[

(* The list of image elements begins *)
 base = Graphics[{LightBlue, EdgeForm[{Thin, Black}],
    Polygon[{{0, 0}, {2, 0}, {2, 2*Tan[\[Pi]/8]}}]}];

 brick1 =
  Graphics[{LightRed, EdgeForm[{Thin, Black}],
    Translate[
     Rotate[Polygon[{{0, 0}, {0.5, 0}, {0.5, 0.25}, {0., 0.25}, {0,
         0}}], 0.392], {0.693, 0.417}]}];

 arr1 = Graphics[{Red, Thick,
    Arrow[{{0.944, 0.514}, {0.944 - 0.4 Sin[\[Pi]/8],
       0.514 + 0.4 Cos[\[Pi]/8]}}]}];
 arr2 = Graphics[{Blue, Thick,
    Arrow[{{0.944 + 0.044,
       0.514 - 0.086}, {0.944 + 0.044 - 0.5 Cos[\[Pi]/8],
       0.514 - 0.5 Sin[\[Pi]/8] - 0.086}}]}];
 arr3 = Graphics[{Brown, Thick,
    Arrow[{{0.944, 0.514}, {0.944, 0.1}}]}];
 txtN = Graphics[
   Text[Style["N", Italic, 18, Red, Bold], {0.874, 0.902}]];
 txtmg = Graphics[
   Text[Style["mg", Italic, 18, Brown, Bold], {1.062, 0.148}]];
 txtkN = Graphics[
   Text[Style["F=kN", Italic, 18, Blue, Bold], {0.342 + 0.125,
     0.46 - 0.11}]];
 arc = Graphics[Circle[{0, 0}, 0.5, {0, \[Pi]/8}]];
 txt3 = Graphics[Text[Style["\[Alpha]", 18], {0.546, 0.12}]];
 line1 = Graphics[{Thick,
    Line[{{1.172, 0.632}, {1.172 + 0.806*Cos[\[Pi]/8],
       0.632 + 0.806*Sin[\[Pi]/8]}}]}];
 disk = Graphics[{LightBlue, EdgeForm[{Thin, Black}],
    Disk[{2, 2*Tan[\[Pi]/8] + 0.1}, 0.1]}];
 line2 = Graphics[{Thick,
    Line[{{2.1 - 0.015, 2*Tan[\[Pi]/8] + 0.04}, {2.1 - 0.015,
       Tan[\[Pi]/8] + 0.04}}]}];

(* It is the brick2 element that is not settled yet *)
brick2 =
  Graphics[{LightRed, EdgeForm[{Thin, Black}],
    Polygon[{{x1, y1}, {x1, y2}, {x2, y2}, {x2, y1}, {x1, y1}}]}];
(* End of the brick2 element *)

 arr4 = Graphics[{Green, Thick,
    Arrow[{{1.172, 0.632}, {1.172 + 0.3*Cos[\[Pi]/8],
       0.632 + 0.3*Sin[\[Pi]/8]}}]}];
 arr5 = Graphics[{Green, Thick,
    Arrow[{{2.1 - 0.015, Tan[\[Pi]/8] + 0.04}, {2.1 - 0.015,
       Tan[\[Pi]/8] + 0.3}}]}];
 arr6 = Graphics[{Black, Thick,
    Arrow[{{2.1 - 0.015, Tan[\[Pi]/8] - 0.04}, {2.1 - 0.015,
       Tan[\[Pi]/8] - 0.04 - 0.3}}]}];
 txtT1 = Graphics[
   Text[Style["T", 18, Italic, Bold, Green], {1.395, 0.83}]];
 txtT2 = Graphics[
   Text[Style["T", 18, Italic, Bold, Green], {2.172, 0.605}]];
 txtMg = Graphics[
   Text[Style["Mg", 18, Italic, Bold, Black], {2.206, 0.13}]];

 (*here the elements are unified making the sketch*)

 Show[{base, brick1, arr1, arr2, arr3, txtN, txtmg, txtkN, arc, txt3,
   line1, disk, line2, brick2, arr4, arr5, arr6, txtT1, txtT2, txtMg}],

(* The envelope of the Manipulate statement closes *)
 {x1, 0, 2.5}, {y1, 0, 2.5}, {x2, 0, 2.5}, {y2, 0, 2.5}
 ]

Just evaluate it and play with the sliders. After all elements of the drawing are settled, I remove the Manipulate statement.

2. A very basic, but astonishingly powerful idea would be to use geometric calculations everywhere you can, to determine the lengths, angles, radii and so on. I mean that if one draws say, a right triangle and knows the angle and one leg, one may calculate the coordinates of the remaining point using simple formulas, and this calculation can be substituted as the parameter into the Polygon statement which will draw the triangle. The example is the base statement of the above drawing. Assume that I only know its left edge at {0,0}, the right bottom edge at {2,0} and the angle, pi/8, between the bottom leg and the hypothenuse. This makes:

Graphics[Polygon[{{0, 0}, {2, 0}, {2, 2*Tan[\[Pi]/8]}}]]

Try this. One may also think about calculating the unknown angles using known dimensions. To give a simple example, let us take the base like in the previous example but take it with the legs lengths 2 and 1. Assume that we want to place a disk such that the projection of its centre onto x is exactly at x=3, while the disk centre lies on the prolongation of the base hypothenuse. Assume further that the disk centre should be connected by a straight line with the upper vertex of the base. It is done by the code below, where k denotes the tangent of the smaller angle of the base:

k = 1/2.;
Show[{
  Graphics[Polygon[{{0, 0}, {2, 0}, {2, 1}}]],
  Graphics[{Blue, Disk[{3, 3*k}, 0.3]}],
  Graphics[Line[{{2, 1}, {3, 3*k}}]]
  }]
 
Try it. An advantage is that you place the point (in this case - the disk centre, and the end of the straight line) very accurately. It comes especially astonishingly, in a more complex drawings when you need to place several elements in contact. If you use this method the elements never come across the boundary of one another. Altogether it looks like a professional technical drawing.

3. When drawing geometric elements I often use those I know the values. For example, if it is not specified otherwise, and if I need to draw a triangle, I would more readily choose to draw a triangle with the angle of 30 grad, since I know the values of its sin,  and so on.

4. Make a collection with all the drawings and drawing elements that you had ever done. Use the mathgroup answers to add to your collection, if suitable. Do it in a special file dedicated only to that, and think in advance about its comprehensible division into Sections, Subsections etc. Like this you may often simply take the already existing drawing element and use it directly or with minor modifications. Somebody who never did such a collection cannot imagine, how fast such a collection grows, and how much acceleration it offers to its user after as short as 1-2 years (let alone 5-9 years).

As you see my tricks are trivial, but taken together they strongly accelerate my work. I hope they help you also.



Dushan, just one comment concerning hiding of the code. If you already know all these things, just skip it.

If you need to hide the code from the readers you may of course do the drawing in the separate notebook. I also do that sometimes. Instead of copy-pasting, however, I do the following. I give the name to my drawing like the following:

baseWithTwoBricks= Show[{base, brick1, arr1, arr2, arr3, txtN, txtmg, txtkN, arc, txt3,
   line1, disk, line2, brick2, arr4, arr5, arr6, txtT1, txtT2, txtMg}]

You only need to give the name to the Show statement, as above. After evaluation you may put the name only:
 
baseWithTwoBricks

into you notebook with the text for readers, into its input cell and execute it. The output cell will contain your drawing. Then I hide the input with this name using the method 1 or 2 described below.

There are several ways to hide your code from the reader, and you may chose one depending upon your precise need.

1. The most simple one is to collapse the input cell by clicking on the bracket of the output cell (at the right margin of your notebook). Like this you are able to open the code any moment. I use this method, when I still work on document, but want to decrease its space in order to simplify navigation.

2. A very powerful method is to close the input cell. I make this after I have already finished with the drawing and it is for sure that the drawing will not be further changed. At least, not soon. Provided I have already executed the code and have the image in the output cell, I go to Menu/Cell/Cell Properties and uncheck "Open". As the result the input cell will collapse, and only a trace of it is left. This trace has the form of a narrow bracket. You may later use this narrow bracket to open this cell once more, if needed. For this you mark this narrow bracket, go to Menu/Cell/Cell Properties and check "Open".

3. You may collect all the code used within the document into a special cell, typically in the beginning or in the end of your document. It is here where your image names (like the baseWithTwoBricks in the example above) are defined. The input cells will only call these image names. It can further be collapsed say, by the method 2.

4. This is the method you actually described, i.e. to keep a separate notebook with all definitions.

In fact I use typically the methods 1 and 2, since I like to keep all the code with my document to be able to come there later and to make changes, or to check, how did I come to the results described in the text. This, however, mainly concerns my technical or scientific documents.

However, I often need to make a technical document that should be further distributed as a pdf file. Then I make all coding in a separate notebook (exactly as you do), since Mathematica is very capriciously when makeing the pdf, if it contains a lots of code, and especially, if the code is interactive. By the way the same is also true for heavy drawings. A good idea, therefore, would be to compress such drawings (say, by Rasterize) before placing then into the notebook to be transformed into pdf.

The method number 3 is the only choice, if you are making an interactive no tebook, and the reader needs to evaluate your code when he starts reading it. Then it can be done using the initialization.

Finally, there is the StyleSheet entitled "Article" in the StyleSeet collection. This style is most close to what I need, and I modified it to suit better my needs. The documents created within this StyleSheet has the possibility to attribute the style "Figure" to the drawing. One does not find "Figure" in most other StyleSheets. (I should admit that I did not check all the styles, and it may exist somewhere else, but at least not in the most polular StyleSheets). I always mark the images I am doing as a Figure, which seems to give additional advantages. 

Have fun, Alexei  
    



Alexei BOULBITCH, Dr., habil.
IEE S.A.
ZAE Weiergewan,
11, rue Edmond Reuter,
L-5326 Contern, LUXEMBOURG

Office phone :  +352-2454-2566
Office fax:       +352-2454-3566
mobile phone:  +49 151 52 40 66 44

e-mail: alexei.boulbitch at iee.lu


-----Original Message-----
From: Dushan Mitrovich [mailto:dushanm at spinn.net]
Sent: Friday, September 21, 2012 5:38 PM
To: Alexei Boulbitch
Cc: mathgroup at smc.vnet.net
Subject: [mg128210] Re: creating a graphic in a text cell

On Thu, 20 Sep 2012 08:32:33 +0000, Alexei Boulbitch wrote:
> I'm teaching a statics course that naturally requires a lot of
> depictions of ropes, springs, pulleys, etc.  To produce a graphic box
> I use Ctrl-1 and use the tool palette.  This works, a bit painfully,
> but recently I ran into a need to depict angles with short arcs.  I
> couldn't find a way of doing that that the graphic box would accept.
>
> Is there a way to specify an arc, and if so, how?  I'm running
> Mathematica
> 8.0.4.0 under Mac OS X.6.8.  Thanks.
>
> - Dushan Mitrovich
>
>
> Hi, Dushan,
>
> There is a primitive Circle[] in which you can make a circular arc.
> Just check Menu/Help/Circle. You may build it iby its evaluation in
> your notebook, and then you can draw down your sketch around the
> already existing arc.
>
> I also make a lot of drawings illustrating technical texts done in
> Mathematica. These drawings are not exactly as yours (i.e. to teach
> something), but they are rather comparable. Since already long time I
> refused of using the Drawings palette. Instead I do it
> programmatically using graphics primitives. The reason is that in the
> same drawing I often combine some elements obtained by one of plotting
> operations (like say, Plot[]) with other elements that previously I
> have produced with the palette. Typically as soon as I end up with
> drawing, I realized that have missed something in the plot, and need
> to make it once more. That means that I need to make also the whole
> palette-based drawing once again.
>
> After having started drawing with primitives I simply need to
> re-evaluate the whole code.
>
> As the example I just sketched below a simple static problem. You will
> find there the element entitled arc with the construct you asked about
> in your post about.
>
> Evaluate the code below.
>  
> (* These are definitions of all elements of the sketch *)
>
> base = Graphics[{LightBlue, EdgeForm[{Thin, Black}],
>     Polygon[{{0, 0}, {2, 0}, {2, 2*Tan[\[Pi]/8]}}]}];
>
> brick1 = Graphics[{LightRed, EdgeForm[{Thin, Black}],
>     Translate[
>      Rotate[Polygon[{{0, 0}, {0.5, 0}, {0.5, 0.25}, {0., 0.25}, {0,
>          0}}], 0.392], {0.693, 0.417}]}];
>
> arr1 = Graphics[{Red, Thick,
>     Arrow[{{0.944, 0.514}, {0.944 - 0.4 Sin[\[Pi]/8],
>        0.514 + 0.4 Cos[\[Pi]/8]}}]}];
> arr2 = Graphics[{Blue, Thick,
>     Arrow[{{0.944 + 0.044,
>        0.514 - 0.086}, {0.944 + 0.044 - 0.5 Cos[\[Pi]/8],
>        0.514 - 0.5 Sin[\[Pi]/8] - 0.086}}]}];
> arr3 = Graphics[{Brown, Thick, Arrow[{{0.944, 0.514}, {0.944,
> 0.1}}]}]; txtN = Graphics[
>    Text[Style["N", Italic, 18, Red, Bold], {0.874, 0.902}]]; txtmg =
> Graphics[
>    Text[Style["mg", Italic, 18, Brown, Bold], {1.062, 0.148}]]; txtkN
> = Graphics[
>    Text[Style["F=kN", Italic, 18, Blue, Bold], {0.342 + 0.125,
>      0.46 - 0.11}]];
> arc = Graphics[Circle[{0, 0}, 0.5, {0, \[Pi]/8}]];
> txt3 = Graphics[Text[Style["\[Alpha]", 18], {0.546, 0.12}]];
> line1 = Graphics[{Thick,
>     Line[{{1.172, 0.632}, {1.172 + 0.806*Cos[\[Pi]/8],
>        0.632 + 0.806*Sin[\[Pi]/8]}}]}]; disk = Graphics[{LightBlue,
> EdgeForm[{Thin, Black}],
>     Disk[{2, 2*Tan[\[Pi]/8] + 0.1}, 0.1]}];
> line2 = Graphics[{Thick,
>     Line[{{2.1 - 0.015, 2*Tan[\[Pi]/8] + 0.04}, {2.1 - 0.015,
>        Tan[\[Pi]/8] + 0.04}}]}];
> brick2 = Graphics[{LightRed, EdgeForm[{Thin, Black}],
>     Polygon[{{2.01, 0.4542}, {2.01 + 0.15, 0.4542}, {2.01 + 0.15,
>        0.3}, {2.01, 0.3}, {2.01, 0.4542}}]}];
> arr4 = Graphics[{Green, Thick,
>     Arrow[{{1.172, 0.632}, {1.172 + 0.3*Cos[\[Pi]/8],
>        0.632 + 0.3*Sin[\[Pi]/8]}}]}];
> arr5 = Graphics[{Green, Thick,
>     Arrow[{{2.1 - 0.015, Tan[\[Pi]/8] + 0.04}, {2.1 - 0.015,
>        Tan[\[Pi]/8] + 0.3}}]}];
> arr6 = Graphics[{Black, Thick,
>     Arrow[{{2.1 - 0.015, Tan[\[Pi]/8] - 0.04}, {2.1 - 0.015,
>        Tan[\[Pi]/8] - 0.04 - 0.3}}]}];
> txtT1 = Graphics[
>    Text[Style["T", 18, Italic, Bold, Green], {1.395, 0.83}]];
> txtT2 = Graphics[
>    Text[Style["T", 18, Italic, Bold, Green], {2.172, 0.605}]]; txtMg ==

> Graphics[
>    Text[Style["Mg", 18, Italic, Bold, Black], {2.206, 0.13}]];
>
> (* here the elements are unified making the sketch *) Show[{base,
> brick1, arr1, arr2, arr3, txtN, txtmg, txtkN, arc, txt3,
>   line1, disk, line2, brick2, arr4, arr5, arr6, txtT1, txtT2, txtMg}]
>
> One can also easily parameterize it and make a movie out of a static
> drawing.
>
> Drawing with primitives goes a bit slower than that with the palette,
> but still astonishingly fast. It took me about 10 minutes to draw
> this. There is a simple trick to accelerate the process. Just ask me,
> if you would find it interesting to learn about it.
>
> Have fun,
> Alexei
>
> Alexei BOULBITCH, Dr., habil.
> IEE S.A.
> ZAE Weiergewan,
> 11, rue Edmond Reuter,
> L-5326 Contern, LUXEMBOURG
>
> Office phone :  +352-2454-2566
> Office fax:       +352-2454-3566
> mobile phone:  +49 151 52 40 66 44
>
> e-mail: alexei.boulbitch at iee.lu
>

Hi Alexei,

Your suggestion and example code were very useful - thanks.  Your comments make a strong case that the Graphics palette is useful only for the most basic uses and not helpful beyond that.  The example code you supplied works just fine on my system.  Since I don't want to have the graphics instructions appear in the instructional material, I can have the instructions in a separated notebook, generate the graphic, then just paste it where I need it.

In fact, I could make a collection of basic-shape instructions, select and copy the ones I need, tailor them for the specific graphic, and execute.  This could speed things up considerably after a while.

Yes, I am very interested to learn the acceleration trick you mention.

- Dushan





  • Prev by Date: Re: regression MIMO problem, fix the parameters
  • Next by Date: sudoku solver
  • Previous by thread: Re: creating a graphic in a text cell
  • Next by thread: Re: Re: creating a graphic in a text cell