Подтвердить что ты не робот

Как определить PlotRange, чтобы включить всю графику?

Учитывая объект Graphics, как определить диапазон координат, необходимых для включения всей графики? В основном мне нужно что-то вроде того, что по умолчанию Show, но я хочу явно указать PlotRange, PlotRangePadding и ImagePadding.

Например, два Show ниже должны отображать один и тот же

g = Graphics[{Thickness[1], CapForm["Round"], Line[{{0, 0}, {1, 1}}]}];
Show[g]
Show[g, PlotRange -> getPlotRange[g], PlotRangePadding->getPlotRangePadding[g], ImagePadding->getImagePadding[g]]

Мотивация: фиксация диаграмм в этом вопросе

Update: AbsoluteOptions дает мне PlotRange, но не два других варианта. Явное указание ImagePadding->Automatic изменяет внешний вид, хотя предположительно Automatic по умолчанию.

Два изображения ниже показывают по-другому, и я не понимаю, почему

g = Graphics[{Thickness[1], CapForm["Round"], Line[{{0, 0}, {1, 1}}]}];
Show[g]
Show[g, Sequence @@ AbsoluteOptions[Show[g]]]

Обновление 2: Аналогичная проблема была поднята год назад, без каких-либо решений, предложенных и не фиксированных по Mathematica 8.0. Подводя итог

  • Невозможно воспроизвести Show[g] выше с явной установкой PlotRange
  • Нет способа получить абсолютный ImagePadding, используемый Show[g]
  • Show[g,PlotRange->Automatic] отличается от Show[g]
  • AbsoluteOptions может дать неправильный результат для PlotRange
4b9b3361

Ответ 1

Я могу предложить следующий Ticks hack:

pl = Plot[Sin[x], {x, 0, 10}];
Reap[Rasterize[Show[pl, Ticks -> {Sow[{##}] &, Sow[{##}] &}, ImageSize -> 0], 
   ImageResolution -> 1]][[2, 1]]

=> {{-0.208333, 10.2083}, {-1.04167, 1.04167}} 

Фокус в том, что реальный PlotRange определяется FrontEnd, а не ядром. Поэтому мы должны заставить FrontEnd визуализировать графику, чтобы оценивать функции tick. Этот хак дает полный PlotRange с явным значением PlotRangePadding.

Более общее решение, учитывая возможность того, что pl имеет нестандартное значение параметра DisplayFinction и что у него может быть опция Axes установлена ​​на False:

completePlotRange[plot:(_Graphics|_Graphics3D|_Graph)] := 
 [email protected]@
   [email protected][
     Rasterize[
      Show[plot, Axes -> True, Frame -> False, Ticks -> (Sow[{##}] &), 
       DisplayFunction -> Identity, ImageSize -> 0], ImageResolution -> 1]]

Можно получить точный PlotRange (без добавления PlotRangePadding) со следующей функцией:

plotRange[plot : (_Graphics | _Graphics3D | _Graph)] := 
 [email protected]@
   [email protected][
     Rasterize[
      Show[plot, PlotRangePadding -> None, Axes -> True, Frame -> False, 
       Ticks -> (Sow[{##}] &), DisplayFunction -> Identity, ImageSize -> 0], 
      ImageResolution -> 1]]

P.S. На странице "Документация" для PlotRange в разделе "Дополнительная информация" можно прочитать: "AbsoluteOptions дает фактические параметры для параметров, используемых внутри Mathematica , когда заданное значение Automatic или All." (внимание мое). Таким образом, похоже, что Документация даже не гарантирует, что AbsoluteOptions даст правильные значения для PlotRange, если это не Automatic или All.

Ответ 2

Я тоже иногда сбиваю с толку, как заставить Mathematica отображать Graphics согласованным образом, особенно при вставке графики.

Для указанного рисунка g не имеет значения, что вы предоставляете для PlotRange, потому что Thickness[1] всегда рисует линию, толщина которой равна диапазону горизонтальных графиков. В вашем примере Show[g, ___] дает правильный результат:

automatic image padding.

Show[g], или просто g, является аномальным.

Почему?

Я не знаю, где/если это задокументировано, но вот несколько вещей, которые могут иметь отношение к вопросу.

  • Очевидно, DisplayForm[Graphics[___]] является растром.

  • Мы можем получить растр для g, используя Rasterize [g]. Что такое RasterSize? От проб и я обнаружил, что RasterSize имеет разрешение экрана 10 * (в моей системе - 72 пикселя на дюйм). Откуда я знаю это? Если я растеризую g с разрешением менее 718, я получаю изображение с размерами {360,361}, тогда как размер изображения по умолчанию для g составляет 360 пикселей в моей системе, поэтому я рисую, чтобы показать [] графику Mathematica Rasterize на 10x разрешение экрана. Кто-нибудь знает, правда ли это? Вы можете получить разрешение экрана (по крайней мере, как это видит Mathematica) от инспектора опционов. Edit То, что следующее выражение оценивается как True, похоже, показывает, что отображаемая графика растрируется в ImageSize: ImportString[ExportString[Show[g,ImageSize->100],"PNG"]] === ImportString[ExportString[Rasterize[g,RasterSize->100,ImageSize->100],"PNG"]

  • Воспроизведение Show[g] при использовании PlotRange Мне нужно использовать Show[g,PlotRange->{{0,1},{0,1}},ImagePadding->90.3]

specific image padding

чтобы получить обрезку по периметру линии. Поэтому кажется, что Mathematica говорит правду, что PlotRange {{0,1},{0,1}} при использовании AbsoluteOptions[]. Он не сообщает фактическое значение ImagePadding. Возможно, потому что ImagePadding->Automatic основан на правиле, которое использует текущие настройки ImageSize, PlotRangeClipping,...? ImagePadding из 90.3 работает только для ImageSize->360; установка ImageSize->200 делает значение ImagePadding неправильным. Для вашей графики ImagePadding->90.3*OptionValue[ImageSize]/360 воспроизводит Show[g,ImageSize->_] в моей системе.

Это все, что я обнаружил до сих пор.

Ответ 3

Вы можете попробовать добавить распознаваемый объект в известном месте, а затем посмотреть, где он отображается в экспортируемой версии, чтобы предоставить ссылку на масштаб. Я думал, что векторный экспорт (SVG или EPS) будет легче разбирать, но я думаю, что растровое воспроизведение будет немного легче, если немного поиграть.

Например, добавьте зеленый прямоугольник, покрывающий теоретический диапазон графика:

g = Graphics[{Blue, Thickness[1], CapForm["Round"], 
   Line[{{0, 0}, {1, 1}}], Green, Rectangle[{0, 0}, {1, 1}]}];

enter image description here

im = Rasterize[g, ImageSize -> 360];
xy = Transpose[Position[ImageData[im], {0., 1., 0.}]];
pad = Map[{Min[#1], 360 - Max[#1] } &, xy];
Show[g, ImagePadding -> pad]

Код в основном определяет, где находятся все зеленые пиксели. Прокладка в этом случае - {{92, 92}, {92, 92}}, но она не должна быть симметричной.