查找绘图的最终显示区域中的框架/轴的坐标

发布于 2024-10-31 06:19:47 字数 287 浏览 1 评论 0原文

如果我使用 Frame->True 进行绘图,有没有办法可以在图像的绝对坐标中找到框架角的坐标?我有 PlotRange 和 PlotRangePadding 的数值,但请注意,我不想以任何方式篡改实际绘图,只需找出 Mathematica 在完整显示区域中选择放置绘图的框架/轴的位置即可。

正如 Brett Champion 所指出的,我正在寻找坐标 {x,y} 使得 Scaled[{0,0}] == ImageScaled[{x,y}]。

[请注意,我编辑了这个问题,以消除对术语“缩放坐标”的令人困惑的误用。]

If I do a Plot with Frame->True is there a way I can find the coordinates of the corners of the Frame in the absolute coordinates of the image? I have the numerical values of PlotRange and PlotRangePadding but note that I don't want to tamper with the actual plot in any way, just find out where in the full display area Mathematica chooses to place the frame/axes of the plot.

As pointed out by Brett Champion, I'm looking for the coordinates {x,y} such that Scaled[{0,0}] == ImageScaled[{x,y}].

[Note that I edited this question to remove my confusing misuse of the term "scaled coordinates".]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

内心荒芜 2024-11-07 06:19:47

框架的角位于 Scaled[{0,0}]Scaled[{1,1}] 处。

完整图形(包括标签)的角点位于 ImageScaled[{0,0}]ImageScaled[{1,1}] 处。

它们之间的转换很困难,尽管理论上如果您知道 PlotRangePlotRangePadding 的实际数字设置,则可以转换 Scaled 和用户(未缩放)坐标

根据您的应用程序,您也许还可以使用 MousePosition,它也知道这些事情。

Rasterize(和 HTML 导出)还知道如何在位图/像素坐标系中查找注释的边界框:

In[33]:= Rasterize[
 Plot[Sin[x], {x, 0, 10}, Frame -> True, 
  Prolog -> {LightYellow, 
    Annotation[Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]], "One", 
     "Region"]}], "Regions"]

Out[33]= {{"One", "Region"} -> {{22., 1.33573}, {358.9, 209.551}}}

以下是 dreeves 如何使用 Rasterize 技巧来创建一个函数来准确返回他正在寻找的内容(注意全局变量 imgsz 的假设,它提供了用于光栅化绘图的 ImageSize 选项——框架的坐标取决于该值):

(* Returns the geometry of the frame of the plot: 
   {width, height, x offset, y offset, total width, total height}. *)
geom[p_Graphics] := Module[{q, x1, y1, x2, y2, xmax, ymax},
  q = Show[p, Prolog->{Annotation[Rectangle[Scaled[{0,0}], Scaled[{1,1}]], 
                                  "MAGIC00","MAGIC11"]}];
  {{x1,y1}, {x2,y2}} = Rasterize[q, "Regions", ImageSize->imgsz][[1,2]];
  {xmax,ymax} = Rasterize[p, "RasterSize", ImageSize->imgsz];
  {x2-x1, y2-y1, x1, y1, xmax, ymax}]

The corners of the frame are at Scaled[{0,0}] and Scaled[{1,1}].

The corners of the full graphic (including labels) are at ImageScaled[{0,0}] and ImageScaled[{1,1}].

Converting between them is hard, although in theory it's possible to convert Scaled and user (unscaled) coordinates if you know the actual, numeric, settings for PlotRange and PlotRangePadding.

Depending on your application, you might also be able to use MousePosition, which knows these things as well.

Rasterize (and HTML export) also know how to find bounding boxes of annotations, in a bitmap/pixel coordinate system:

In[33]:= Rasterize[
 Plot[Sin[x], {x, 0, 10}, Frame -> True, 
  Prolog -> {LightYellow, 
    Annotation[Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]], "One", 
     "Region"]}], "Regions"]

Out[33]= {{"One", "Region"} -> {{22., 1.33573}, {358.9, 209.551}}}

Here's how dreeves used that Rasterize trick to make a function to return exactly what he was looking for (note the assumption of a global variable imgsz which gives the ImageSize option for rasterizing the plot -- the coordinates of the frame depend on that value):

(* Returns the geometry of the frame of the plot: 
   {width, height, x offset, y offset, total width, total height}. *)
geom[p_Graphics] := Module[{q, x1, y1, x2, y2, xmax, ymax},
  q = Show[p, Prolog->{Annotation[Rectangle[Scaled[{0,0}], Scaled[{1,1}]], 
                                  "MAGIC00","MAGIC11"]}];
  {{x1,y1}, {x2,y2}} = Rasterize[q, "Regions", ImageSize->imgsz][[1,2]];
  {xmax,ymax} = Rasterize[p, "RasterSize", ImageSize->imgsz];
  {x2-x1, y2-y1, x1, y1, xmax, ymax}]
掌心的温暖 2024-11-07 06:19:47

框架左上角的坐标始终为Scaled[{0,1}]
框架右下角的坐标始终为Scaled[{1,0}]

让我们在左上角和右下角放置大点:

Plot[Cos[x], {x, 0, 10}, Frame -> True, 
Epilog -> {PointSize[.08], Point[Scaled[{0, 1}]], Point[Scaled[{1, 0}]]} ]

当我单击图形(见下文)时,很明显,图框周围没有填充。

no padding

现在,启用 ImagePadding,让我们放置 Point在相同的角上:

Plot[Cos[x], {x, 0, 10}, Frame -> True,  
ImagePadding -> {{37, 15}, {20, 48}}, 
Epilog -> {PointSize[.08], Point[Scaled[{0, 1}]],  Point[Scaled[{1, 0}]]} ]

位于图框的角上。
图框周围有ImagePadding

with padding

编辑:基于 dreeves 对问题的澄清。

Plot[Cos[x], {x, 1, 9}, ImageSize -> 300, AspectRatio -> 1, 
Frame -> True, ImagePadding -> 30, 
FrameTicks -> {Range[9], Automatic}, 
Epilog -> {PointSize[.08], Point[Scaled[{0, 1}]], Point[Scaled[{1, 0}]]}]

Frameticks

我将绘图绘制为 300x300 以简化数字。
这是分析。

  1. 文档指出ImagePadding“是在ImageSize中定义的”。
  2. 上面显示的图像的宽度和高度均为 300 像素。
  3. 框架周围有 30 像素的边距;这相当于宽度和高度的 10%。
  4. 因此,框架角应该从原点开始位于 ImageScaled[{.1,.1}]ImageScaled[{.9,.1}>ImageScaled[{.9,.9}] & ImageScaled[{.1,.9}]

计算其他 AspectRatioImageSize 的值很容易。

The coordinates of the upper left corner of the frame are always Scaled[{0,1}].
The coordinates of the lower right corner of the frame are always Scaled[{1,0}].

Let's place large points at the upper left and lower right corners:

Plot[Cos[x], {x, 0, 10}, Frame -> True, 
Epilog -> {PointSize[.08], Point[Scaled[{0, 1}]], Point[Scaled[{1, 0}]]} ]

When I click on the graph (see below) , it is obvious that there is no padding around the frame of the plot.

no padding

Now, with ImagePadding on, let's place Points in the same corners:

Plot[Cos[x], {x, 0, 10}, Frame -> True,  
ImagePadding -> {{37, 15}, {20, 48}}, 
Epilog -> {PointSize[.08], Point[Scaled[{0, 1}]],  Point[Scaled[{1, 0}]]} ]

The Points stay at the corners of the graph frame.
There is ImagePadding around the graph frame.

with padding

EDIT: Based on the clarification of the question by dreeves.

Plot[Cos[x], {x, 1, 9}, ImageSize -> 300, AspectRatio -> 1, 
Frame -> True, ImagePadding -> 30, 
FrameTicks -> {Range[9], Automatic}, 
Epilog -> {PointSize[.08], Point[Scaled[{0, 1}]], Point[Scaled[{1, 0}]]}]

Frameticks

I've drawn the plot as 300x300 to simplify the numbers.
Here's the analysis.

  1. Documentation states that ImagePadding "is defined within ImageSize".
  2. The image shown above has a width and height of 300 pixels.
  3. There is a 30 pixel margin drawn around the frame; this corresponds to 10% of the width and height.
  4. So the frame corners should be, starting from the origin, at ImageScaled[{.1,.1}], ImageScaled[{.9,.1}, ImageScaled[{.9,.9}] & ImageScaled[{.1,.9}].

It's easy to work out the value for other AspectRatios and ImageSizes.

夜夜流光相皎洁 2024-11-07 06:19:47

一种可能性是手动控制 ImagePadding:

Plot[Sin[x], {x, 0, 10}, Frame -> True, 
 ImagePadding -> {{30, 5}, {20, 5}}]

在此处输入图像描述

ImageTake[Rasterize[%], {5, -20}, {30, -5}]

在此处输入图像描述

One possibility is to take manual control of ImagePadding:

Plot[Sin[x], {x, 0, 10}, Frame -> True, 
 ImagePadding -> {{30, 5}, {20, 5}}]

enter image description here

ImageTake[Rasterize[%], {5, -20}, {30, -5}]

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文