Как определить 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
Ответы
Ответ 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, ___]
дает правильный результат:
.
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}}, но она не должна быть симметричной.