Mathematica:标签和绝对定位

6
如何在Mathematica中将文本定位于图形外部?快速搜索谷歌会带您到以下链接:http://reference.wolfram.com/mathematica/howto/AddTextOutsideThePlotArea.html。然而,这并不足够,因为您想通过代码实现此目的。以下是在Mathematica中放置文本的简单示例:
    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}]]
     ]

这将字母A放置在相对于绘图的点(.5, .5)。有没有一种方法可以根据图像大小来放置文本?据我所知,所有操作都是在绘图坐标系中完成的。我暂时的解决方案是将选项PlotRangeClipping设置为False,并通过给出正确的坐标来设置文本。

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

这种方法的缺点在于,如果我们更改绘图范围,则需要重新计算文本的坐标,以便将其保持在所需位置(相对于整个图像)。

编辑:

尝试将 Text A 定位在图形外部。

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}]
            ]
        ]
    ]
]

输入图像描述

编辑:

为了找到这个问题的另一个解决方案,我开始了另一篇帖子,这给了我克服belisarius解决方案中的一个问题的想法: 将最终图形导出为pdf是图形的栅格化版本。查看我的其他帖子这里的解决方案。

最终编辑?

由于图像链接已经消失,并且上一个编辑中的链接已经被修改,因此我决定更新图片并包括Simon的答案的修改版本。

思路是创建一个掩码,并在绘制标签之前包含该掩码。这样我们就可以创建自己的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}]
    }]
}];

有时使用{1,1}ImageScaled不足以裁剪主图像。因此,我使用了1.5-0.5来提供更多的覆盖范围。现在我们可以按如下方式绘制带有标签的图像:

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
]

这里是所需的图片:

输入图片描述

请注意,我已将图像背景更改为红色。这可以通过更改Background属性轻松修改,对于遮罩,只需将Gray更改为您喜欢的任何颜色(例如白色)。

3个回答

5
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

编辑

回答您关于橙色圆盘部分的问题,问题在于Show将图形选项连接在一起,因此您无法在Show[]命令中为PlotRangeClipping设置多个值。 克服这个问题的一种方法是:

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


感谢您的帖子。这正是我从Verbeia所写的内容中得出的结论。但是,您如何使以下工作?http://i.imgur.com/IL5uJ.png - jmlopez
@jmlopez 请把代码发布在某个地方,这样我就不用重新输入了。谢谢! - Dr. belisarius
1
非常感谢。这正是我在寻找的。你写的函数非常棒 :) - jmlopez
哎呀...Belisarius,我很抱歉再次打扰你,但我刚刚注意到你使用了Rasterize。这是有问题的,因为现在当我导出到pdf或eps时,我们不再拥有矢量图形了。你有解决方法吗? - jmlopez
我发现了这个链接:http://www.mathkb.com/Uwe/Forum.aspx/mathematica/20639/WebMathematica-and-SVG-graphics。在那里有一个样例代码,我可以看出它生成了绘图的svg版本,这意味着我们需要有一种方式来访问XML树,在Mathematica中进行svg编辑。对我来说没问题,这样可以避免我切换到inkscape和python上的痛苦,也不用担心字体的混乱。现在的问题是,我们该如何操作? - jmlopez
显示剩余3条评论

3

谢谢Verbeia。我不知道为什么我从来没有遇到过ImageScaled。这解决了绝对坐标的问题。然而,只有在我们将PlotRangeClipping设置为False时才有效。有些情况下,您希望将PlotRangeClipping设置为True,但仍然能够将一些文本放在绘图区域之外。有些东西告诉我我将不得不在这里使用Inset,但我仍然不确定如何做。 - jmlopez
试试使用ImagePadding代替PlotRangeClipping怎么样? - Verbeia
以下是一个示例,展示了当您想要PlotRangeClipping为True时的情况。http://i.imgur.com/IL5uJ.png。请注意,文本A仅出现在图表中而不是外部。 - jmlopez

2
也许你可以尝试使用网格布局(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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接