Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mathematica: Labels and absolute positioning

How do you position a text outside a plot in mathematica? A quick google search will lead you to

http://reference.wolfram.com/mathematica/howto/AddTextOutsideThePlotArea.html

This is not enough since you want to achieve this with code. A simple example of placing text in mathematica is the following:

    Show[ 
     Plot[x^3, {x, -1, 1},
      Frame -> True, 
      ImageSize -> Medium, 
      FrameLabel -> {"x", "y"},
      PlotRange -> {{-1, 1}, {-1, 1}}
      ],
     Graphics[
      Text[Style["A", Bold, 14, Red], {.5, .5}]]
     ]

This places the letter A at the point (.5, .5) relative to the plot. Is there a way of placing text relative to the size of image? Everything is done in the plot coordinates as far as I know. The temporary solution I have is to set the option PlotRangeClipping to False and set the text by giving the right coordinates.

Show[
    Plot[
        x^3, {x, -1, 1}, 
        Frame -> True, 
        ImageSize -> Medium, 
        FrameLabel -> {"x", "y"}, 
        PlotRange -> {{-1, 1}, {-1, 1}}
    ],
    Graphics[
        Text[
            Style["A", Bold, 14, Red], 
            {-1.2, 1}
        ]
    ],
    PlotRangeClipping -> False
]

currentsolution

A disadvantage of this method is that if we change the range of the plot then we need to recalculate the coordinates of the text in order to keep it where we want it (relative to the whole image).

EDIT:

Try to position the Text A outside the plot.

Framed[
    Show[
        Graphics[
            {Orange, Disk[{0, 0}, 3.5]}, 
            Frame -> True, 
            PlotRange -> {{-3, 3}, {-3, 3}}, 
            PlotRangeClipping -> True, 
            FrameLabel -> {"x", "y"}
        ], 
        Graphics[
            Text[
                Style["A", Bold, 14], 
                ImageScaled[{.1, .95}]
            ]
        ]
    ]
]

enter image description here

EDIT:

In order to find another solution to this problem I started another post which gave me ideas to overcome a problem that belisarius solution had: Exporting the final figure to pdf was a rasterized version of the figure. Check my other post here for the solution.

FINAL EDIT?

Since the image links are gone and the link in the previous edit has been modified I decided to update the images and include a modified solution of Simon's answer.

The idea is to create a mask and include the mask before drawing the labels. In this way we are creating our own plotRangeClipping.

mask2D = Graphics[{Gray,
    Polygon[{
        ImageScaled[{-0.5, -0.5}],
        ImageScaled[{-0.5, 1.5}],
        ImageScaled[{1.5, 1.5}],
        ImageScaled[{1.5, -0.5}],
        ImageScaled[{-0.5, -0.5}],
        Scaled[{0, 0}],
        Scaled[{1, 0}],
        Scaled[{1, 1}],
        Scaled[{0, 1}],
        Scaled[{0, 0}],
        ImageScaled[{-0.5, -0.5}]
    }]
}];

In some cases using ImageScaled of {1,1} is not enough to clip the main image. For this reason I have given more coverage by using 1.5 and -0.5. Now we can draw the image with label as follows:

Framed@Show[
    Graphics[
        {
            Orange,
            Disk[{0, 0}, 3.5]
        },
        Frame -> True,
        PlotRange -> {{-3, 3}, {-3, 3}},
        FrameLabel -> {"x", "y"}
    ],
    mask2D,
    Graphics[
        Text[
            Style["A", Bold, 14],
            ImageScaled[{0, 1}],
            {-1, 1}
        ]
    ],
    Background -> Red
]

Here is the desired image:

enter image description here

Notice that I have changed the background of the image to red. This can easily be modified by changing the Background property and for the mask simply change Gray to whatever color you prefer (White) for instance.

like image 588
jmlopez Avatar asked Jun 08 '11 05:06

jmlopez


3 Answers

Plot[x^3, {x, -1, 1},
 Frame -> True,
 ImageSize -> Medium,
 FrameLabel -> {"x", "y"},
 PlotRange -> {{-1, 1}, {-1, 1}}],
 PlotRangeClipping -> False,
 Epilog ->
     Text[Style["A", Bold, 14, Red], ImageScaled@{.05, .98}]

enter image description here

Edit

Answering your orange disk part, the problem is that Show concatenates the Graphics Options, so you can't have several values for PlotRangeClipping inside a Show[ ] command. One way to overcome that is:

InsertLabels[g_Graphics, legend__] := 
  Show[Rasterize[g], 
   Graphics[{legend}, 
    Cases[AbsoluteOptions[g], Except[PlotRangeClipping -> True]]]];

g = Graphics[
   {Gray, Disk[{0, 0}, 3.5]},
   Frame -> True,
   PlotRange -> {{-3, 3}, {-3, 3}},
   FrameLabel -> {"x", "y"},
   PlotRangeClipping -> True];

Framed@InsertLabels[g,
 Text[Style["B", Red, Bold, 18], ImageScaled[{0.95, .05}]], 
 Text[Style["A", Red, Bold, 18], ImageScaled[{0.05, .95}]]]

enter image description here

like image 82
Dr. belisarius Avatar answered Oct 31 '22 15:10

Dr. belisarius


You might have some good results using Inset with coordinates defined using ImageScaled. I'd give you exact code but I don't have a Mathematica install on my work machine.

http://reference.wolfram.com/mathematica/ref/Inset.html http://reference.wolfram.com/mathematica/ref/ImageScaled.html

See also: http://reference.wolfram.com/mathematica/ref/Scaled.html

like image 41
Verbeia Avatar answered Oct 31 '22 16:10

Verbeia


May be you can try Grid?

Grid[{
{
   Text[Style["A",Bold,14,Red]]
},
{
   Plot[x^3,{x,-1,1},
   Frame->True,
   ImageSize->200,
   FrameLabel->{"x","y"},
   PlotRange->{{-1,1},{-1,1}}
   ]
}},Spacings->0,Alignment->Center
]

enter image description here

like image 2
Nasser Avatar answered Oct 31 '22 16:10

Nasser