Как определить PlotRange, чтобы включить всю графику? - PullRequest
33 голосов
/ 27 ноября 2010

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

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

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

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

Обновление : 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. Подведем итог

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

Ответы [ 3 ]

5 голосов
/ 02 сентября 2011

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

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 визуализировать графику, чтобы оценить функции тиков. Этот хак дает полный PlotRange с явным добавлением PlotRangePadding.

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

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

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

plotRange[plot : (_Graphics | _Graphics3D | _Graph)] := 
 Quiet@Last@
   Last@Reap[
     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.

3 голосов
/ 05 февраля 2011

Вы можете попробовать добавить распознаваемый объект в известном месте, а затем посмотреть, где он отображается в экспортированной версии, чтобы предоставить ссылку на масштаб.Я думал, что экспорт вектора (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}}, но оно не обязательно должно быть симметричным.

3 голосов
/ 04 февраля 2011

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

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

automatic image padding.

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

Почему?

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

  1. Очевидно, DisplayForm[Graphics[___]] - это растр.

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

  3. Для воспроизведения 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->_] в моей системе.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...