4

I'm using Asymptote to draw my graphics. I am making a graph of arctan. I want to label the graph, but I want the label to poke outside the bounding box. I want this because if I just let Asymptote include the label in the bounding box then when I put the figure in the document and center it, then it looks off-center (would the right term be that the label doesn't have graphic "weight"?).

Briefly, if change what's below to say \makebox[0em][l]{$\arctan(..)$} then Asymptote clips the text at the bounding box. How do I preserve the bb, but have all of the label appear?

// arctan.asy
import settings;
settings.outformat="pdf";
settings.render=0;

unitsize(1cm);

import graph;
real f(real x) {
  return (atan(x)+(pi/2.0))/pi;
}

real xmin = -3.5;
real xmax = 3.5;
real ymin = -0.35;
real ymax = 1.5;

draw((xmin,0) -- (xmax,0), blue, arrow=None);
draw((0,ymin) -- (0,ymax), blue, arrow = None);

path g = graph(f,xmin,xmax);
draw(g,red);
label("\makebox[0em][c]{$\scriptstyle (\arctan(x)+(\pi/2))/\pi$}", (2.15,0.8), S);

Obviously I can do this one with some fudging by eye. But is there an automatic soution?

5

There's probably an easier way, but here is a solution. The centerAtOrigin function shown in the code below will fill a transparent rectangle over the plot. The rectangle is scaled and centered on the origin such that the graph origin is left-right centered. I've added the black border in the plot below just to illustrate the white border to the left of the plot.

// arctan.asy
import settings;
settings.outformat="pdf";
settings.render=0;

unitsize(1cm);

import graph;
real f(real x) {
  return (atan(x)+(pi/2.0))/pi;
}

real xmin = -3.5;
real xmax = 3.5;
real ymin = -0.35;
real ymax = 1.5;

draw((xmin,0) -- (xmax,0), blue, arrow=None);
draw((0,ymin) -- (0,ymax), blue, arrow = None);

path g = graph(f,xmin,xmax);
draw(g,red);
label("$\scriptstyle (\arctan(x)+(\pi/2))/\pi$", (xmax,0.8), S);

void centerAtOrigin()
{
    pair origMinPoint = min(currentpicture)/72*2.54;
    pair origMaxPoint = max(currentpicture)/72*2.54;
    pair origSize = size(currentpicture)/72*2.54;
    real xmin = origMinPoint.x;
    real xmax = origMaxPoint.x;
    real ymin = origMinPoint.y;
    if (xmax > fabs(xmin)) { xmin = -xmax; }
    if (fabs(xmin) > xmax) { xmax = -xmin; }
    fill(shift(xmin,ymin)*scale(xmax-xmin,origSize.y)*
        unitsquare, opacity(0)+white);
}

centerAtOrigin();

enter image description here

Edit: Instead of showing the label even though it's outside of the bounding box, this method expands the bounding box on the other side to keep your vertical axis centered.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.