2010-11-26 9 views
33

Dado el objeto Graphics, ¿cómo determino el rango de coordenadas necesarias para incluir todos los gráficos? Básicamente necesito algo parecido a lo que Show hace por defecto, pero quiero especificar PlotRange, PlotRangePaddingImagePadding y de forma explícita.¿Cómo se determina que PlotRange incluye todos los gráficos?

ejemplo, dos Show s a continuación deben rendir 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: la fijación de diagramas en cuestión this

actualización: AbsoluteOptions me da PlotRange pero no las otras dos opciones. Especificando explícitamente ImagePadding->Automatic cambia la apariencia aunque se supone que es Automatic por defecto.

dos imágenes siguientes muestran de manera diferente y que no entienden 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 fue brought up hace un año, sin soluciones propuestas, y no se fijan como de Mathematica 8,0 . Para resumir

  1. No hay manera de reproducir Show[g] anterior con ajuste explícito de PlotRange
  2. No hay manera de conseguir absoluta ImagePadding utilizado por Show[g]
  3. Show[g,PlotRange->Automatic] se ve diferente de Show[g]
  4. AbsoluteOptions puede dar la wrong result de PlotRange
+1

Estoy jugando con AbsoluteOptions también, pero a veces devuelve valores erróneos –

+0

Sí ... tal vez sea mejor que implemente mis propias gruesas líneas ... –

+1

Parece que el problema no es nuevo http://thedailyreviewer.com/ compsys/view/problems-absolute-plotrange-108108947 –

Respuesta

3

A veces, también me resulta confuso cómo hacer que Mathematica muestre Graphics de una manera consistente, particularmente cuando inserta gráficos.

Para el gráfico especificado g, no importa lo que proporcione para el PlotRange, porque 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:

automatic image padding.

Show[g], o simplemente g, es anómala.

¿Por qué?

No sé dónde/si esto está documentado, pero aquí hay algunas cosas que pueden ser relevantes para la pregunta.

  1. Obviamente DisplayForm[Graphics[___]] es una trama.

  2. Podemos obtener una trama de g usando Rasterize [g]. ¿Qué es el RasterSize? De la prueba y el 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 que 718, obtengo una imagen con dimensiones {360,361}, mientras que el tamaño de imagen predeterminado para g es de 360 ​​píxeles en mi sistema, por lo que creo que se 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. Editar que la siguiente expresión se evalúa como True parece demostrar que el gráfico que se muestra rasterizar en el ImageSize: ImportString[ExportString[Show[g,ImageSize->100],"PNG"]] === ImportString[ExportString[Rasterize[g,RasterSize->100,ImageSize->100],"PNG"]

  3. para reproducir Show[g] cuando se utiliza PlotRange necesito utilizar Show[g,PlotRange->{{0,1},{0,1}},ImagePadding->90.3]

specific image padding

to ge es para recortar al perímetro de la línea. Entonces, parece que Mathematica está diciendo la verdad que PlotRange es {{0,1},{0,1}} al usar AbsoluteOptions[]. No informa el valor real de ImagePadding. Tal vez porque ImagePadding->Automatic se basa en una regla que usa los ajustes actuales ImageSize, PlotRangeClipping, ... El ImagePadding de 90.3 solo funciona para ImageSize->360; configuración ImageSize->200 hace que el valor 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.

+0

JxB Publique las direcciones de imgurl de sus imágenes y las subiré. –

+0

@belisarius Un upvote me dio suficiente reputación para agregar las imágenes. Gracias por la oferta. – JxB

+0

Es posible que el análisis de la parte 2 de la lista no sea correcto: el ráster mostrado puede estar rasterizado en el tamaño de la imagen ... – JxB

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, añadir un rectángulo verde que cubre la gama gráfico teórico:

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] 

El código está básicamente identificando donde todos los píxeles verdes son. El relleno en este caso es {{92, 92}, {92, 92}}, pero no tiene que ser simétrico.

5

lo que puedo proponer el truco Ticks siguiente:

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 la interfaz, no por el núcleo. 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.

Más solución general teniendo en cuenta la posibilidad de que pl tiene valor no estándar de DisplayFinction opción y que puede haber Axes opción se ajusta a 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]] 

Uno puede conseguir la exacta PlotRange (sin el PlotRangePadding añadido) con la siguiente función:

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. En la página de documentación para PlotRange bajo el "Más información" se puede leer: "AbsoluteOptions da la configuración real de las opciones utilizadas internamente por Mathematicacuando la configuración dado es Automatic o All." (El subrayado es mío). Por lo tanto, parece que la Documentación ni siquiera garantiza que AbsoluteOptions dará valores correctos para PlotRange cuando no sea Automatic o All.

+0

¡Señor, está hecho de victoria! Esa última función es extremadamente útil. –

+0

@El Me alegro de ayudar :) –

Cuestiones relacionadas