wolfram mathematica - tabla - ¿Cómo se determina que PlotRange incluya todos los gráficos?
plot mathematica (3)
Puede intentar agregar un objeto reconocible en una ubicación conocida y luego ver dónde se muestra en la versión exportada para proporcionar una referencia de escala. Pensé que una exportación vectorial (SVG o EPS) sería más fácil de analizar, pero creo que la trama es más fácil después de jugar un poco.
Por ejemplo, agregue un rectángulo verde que cubra el rango teórico de la gráfica:
g = Graphics[{Blue, Thickness[1], CapForm["Round"],
Line[{{0, 0}, {1, 1}}], Green, Rectangle[{0, 0}, {1, 1}]}];
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]
El código básicamente identifica donde están todos los píxeles verdes. El relleno en este caso es {{92, 92}, {92, 92}}, pero no tiene que ser simétrico.
Dado el objeto Graphics
, ¿cómo determino el rango de coordenadas necesarias para incluir todos los gráficos? Básicamente, necesito algo como Show
por defecto, pero quiero especificar PlotRange
, PlotRangePadding
e ImagePadding
.
Ejemplo, dos Show
s a continuación deben representar el mismo
g = Graphics[{Thickness[1], CapForm["Round"], Line[{{0, 0}, {1, 1}}]}];
Show[g]
Show[g, PlotRange -> getPlotRange[g], PlotRangePadding->getPlotRangePadding[g], ImagePadding->getImagePadding[g]]
Motivación: arreglando diagramas en this pregunta
Actualización : AbsoluteOptions
me da PlotRange
pero no las otras dos opciones. Especificando explícitamente ImagePadding->Automatic
cambia la apariencia aunque es supuestamente Automatic
por defecto.
Dos imágenes a continuación muestran de manera diferente y no entiendo por qué
g = Graphics[{Thickness[1], CapForm["Round"], Line[{{0, 0}, {1, 1}}]}];
Show[g]
Show[g, Sequence @@ AbsoluteOptions[Show[g]]]
Actualización 2 : un problema similar surgió hace un año, sin soluciones propuestas, y no se corrigió a partir de Mathematica 8.0. Para resumir
- No hay forma de reproducir
Show[g]
arriba con configuración explícita dePlotRange
- No hay forma de obtener
ImagePadding
absoluto utilizado porShow[g]
-
Show[g,PlotRange->Automatic]
ve diferente deShow[g]
-
AbsoluteOptions
puede dar el resultado incorrecto paraPlotRange
Puedo sugerir el siguiente truco de 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}}
El truco es que el verdadero PlotRange
está determinado por el FrontEnd, no por el Kernel. Por lo tanto, debemos forzar a FrontEnd a representar los gráficos para que se evalúen las funciones de marcación. Este truco proporciona el PlotRange
completo con el valor explícito de PlotRangePadding
agregado.
Solución más general teniendo en cuenta la posibilidad de que pl
tenga un valor no estándar de la opción DisplayFinction
y de que tenga la opción Axes
configurada en 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]]
Uno puede obtener el PlotRange
exacto (sin agregar PlotRangePadding
) con la siguiente función:
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]]
PD En la página de Documentación para PlotRange
debajo de "Más información" se puede leer: " AbsoluteOptions
da la configuración real para las opciones usadas internamente por Mathematica cuando la configuración dada es Automatic
o All
." (Énfasis mío). Por lo tanto, parece que la Documentación ni siquiera garantiza que AbsoluteOptions
proporcione valores correctos para PlotRange
cuando no es Automatic
o All
.
Yo también, a veces, encuentro confuso cómo hacer que Mathematica muestre Graphics
de una manera consistente, particularmente cuando se montan gráficos.
Para el gráfico especificado g
, no importa lo que proporciones para el PlotRange
, porque el Thickness[1]
siempre dibuja una línea cuyo grosor es igual al rango de trazado horizontal. En su ejemplo, Show[g, ___]
da el resultado correcto:
.
Show[g]
, o simplemente g
, es anómalo.
¿Por qué?
No sé dónde / si esto está documentado, pero aquí hay algunas cosas que pueden ser relevantes para la pregunta.
Obviamente
DisplayForm[Graphics[___]]
es un ráster.Podemos obtener un ráster para g usando Rasterize [g]. ¿Qué es el RasterSize? A partir de la prueba y error, encontré que RasterSize es una resolución de pantalla de 10 * (reportada como 72 píxeles por pulgada en mi sistema). ¿Cómo sé esto? Si rasterizo g con resoluciones menores a 718, obtengo una imagen con dimensiones {360,361}, mientras que el tamaño de imagen por defecto para g es de 360 píxeles en mi sistema, así que represento Mostrar [] un gráfico, Mathematica
Rasterize
en 10 veces la resolución de la pantalla. ¿Alguien sabe si esto es cierto? Puede obtener la resolución de su pantalla (al menos como lo ve Mathematica) desde el Inspector de Opciones. Edite que la siguiente expresión se evalúa comoTrue
para mostrar que el gráfico mostrado está rasterizado en ImageSize:ImportString[ExportString[Show[g,ImageSize->100],"PNG"]] === ImportString[ExportString[Rasterize[g,RasterSize->100,ImageSize->100],"PNG"]
Para reproducir
Show[g]
cuando usePlotRange
, necesito usarShow[g,PlotRange->{{0,1},{0,1}},ImagePadding->90.3]
para hacer que se recorta al perímetro de la línea. Parece que Mathematica está diciendo la verdad que el PlotRange
es {{0,1},{0,1}}
cuando se usa AbsoluteOptions[]
. No informa el valor real de ImagePadding
. Tal vez porque ImagePadding->Automatic
se basa en una regla que usa los ImageSize
actuales de ImageSize
, PlotRangeClipping
, ... El ImagePadding
de 90.3 solo funciona para ImageSize->360
; al configurar ImageSize->200
hace que el valor de ImagePadding
sea incorrecto. Para su gráfico, ImagePadding->90.3*OptionValue[ImageSize]/360
reproduce Show[g,ImageSize->_]
en mi sistema.
Eso es todo lo que he descubierto hasta ahora.