Solución:
Podrías “abusar” Arrowheads
para este propósito; tiene la ventaja de rastrear los ejes dondequiera que se muevan. Aquí hay una función de utilidad toArrowheads
:
toArrowheads[{x_, y_}, head_, size_: 0.015, xos_: {-3, -3}, yos_: {-3, 3}] :=
{Arrowheads[{{size, 1, Graphics[{head, Inset[x, xos]}]}}],
Arrowheads[{{size, 1, Graphics[{head, Inset[y ~Rotate~ (-90 °), yos]}]}}]}
El primer parámetro es una lista con etiquetas “x” e “y” suplementarias que pueden ser expresiones arbitrarias. El segundo parámetro es el gráfico de punta de flecha base. Los siguientes tres parámetros son opcionales y controlan el tamaño de la punta de flecha y el desplazamiento de las etiquetas “x” e “y”.
En uso:
head = Polygon[{{-3, 1}, {0, 0}, {-3, -1}, {-2.2, 0}}];
ParametricPlot[{Sin[t], Cos[t]}, {t, 0, 2 π},
Frame -> True,
AxesStyle -> toArrowheads[Style[#, 20] & /@ {"x", "y"}, head],
PlotRangePadding -> 0.2,
PlotRange -> {-0.8, 1.2},
AxesOrigin -> {-0.1, 0.3}
]
Podrías usar Epilog
para poner las etiquetas allí manualmente:
ParametricPlot[{Sin[t], Cos[t]}, {t, 0, 2 [Pi]}, Frame -> True,
AxesStyle -> Arrowheads[0.04], PlotRangePadding -> 0.2,
Epilog -> {Inset["x", Scaled[{0.95, 0.48}]], Inset["y", Scaled[{0.48, 0.95}]]}]
solía Scaled
por lo que no importa qué tan grande sea el círculo (y funciona bien con PlotRangePadding
).
Versión asimétrica: aún no se ha probado en profundidad
Basado en los comentarios del Sr. Wizards, pensé en ideas asimétricas. Mostró cómo “abusar” de las puntas de flecha; intentaré algo diferente aquí (tenga en cuenta que el código se puede optimizar, pero lo mantengo bastante extenso para mostrar lo que estaba pensando):
Lo que hago: obtengo el PlotRange
, AxesOrigin
y PlotRangePadding
y calcular la posición:
doPP[pp_] :=
Module[{plotRange, plotRangePadding, axes, offset},
plotRange = Extract[pp, Most /@ Position[pp, PlotRange]][[1, 2]];
plotRangePadding = {[email protected]#, [email protected]#} &@
Extract[pp, Most /@ Position[pp, PlotRangePadding]][[1, 2]];
axes = [email protected][pp, Most /@ Position[pp, AxesOrigin]][[1, 2]];
offset =
Rescale[#1, #2] & @@@ Transpose[{axes, plotRangePadding + # & /@ plotRange}];
Show[pp,
Epilog -> {Inset["x", Scaled[{ 0.95, offset[[1]] - 0.02}]],
Inset["y", Scaled[{offset[[2]] - 0.02, 0.95}]]}]]
donde puedes personalizar 0.02
y 0.95
a su gusto (o establecer como opciones, parámetros).
Podemos ejecutar ahora:
ParametricPlot[{Sin[t], Cos[t]}, {t, 0, 2 [Pi]}, Frame -> True,
AxesStyle -> Arrowheads[0.04], PlotRangePadding -> 0.2,
AxesOrigin -> {0.3, 0.5}, PlotRange -> {-0.2, 1.3}] // doPP
Aquí hay otra forma, basada en esta respuesta de Alexey Popkov. Es un poco más lento que los demás debido a Rasterize
, pero maneja posiciones de ejes asimétricas. También se podría usar Offset
en lugar de {3.5, 2.}
para manejar la compensación de las etiquetas, o hacer los argumentos de compensación para labelaxes
.
labelaxes[plot_, {xlabel_, ylabel_}] :=
Module[{xlim, ylim, orig},
Rasterize[
Show[plot, Frame -> False, Ticks -> {(xlim = {##}) &, (ylim = {##}) &}],
ImageResolution -> 1];
orig = AxesOrigin /. AbsoluteOptions[plot, AxesOrigin];
Show[plot,
Graphics[{
Text[TraditionalForm[xlabel], {xlim[[2]], orig[[2]]}, {3.5, 2.}],
Text[TraditionalForm[ylabel], {orig[[1]], ylim[[2]]}, {3.5, 2.}]}]
]
]
labelaxes[
ParametricPlot[{Sin[t], Cos[t]} + {0.1, 0.2}, {t, 0, 2 Pi},
Frame -> True, AxesStyle -> Arrowheads[0.04], PlotRangePadding -> 0.2], {x, y}]
Suprimo el marco para que se muestren los ejes:
labelaxes[
ParametricPlot[{Sin[t], Cos[t]} + {2, 4}, {t, 0, 2 Pi},
(*Frame -> True,*) AxesStyle -> Arrowheads[0.04], PlotRangePadding -> 0.2], {x, y}]