2D plot looks wrong in sage

82 views
Skip to first unread message

Karsten

unread,
Nov 8, 2010, 6:00:53 PM11/8/10
to sage-support
I am a beginner using sage, and I have encountered a problem using the
plot function. Plotting a simple sine or cosine function is not very
precise:

t=var('t')
v=plot(sin(t),-pi,pi

The function is clearly positive in t=-pi, where it should be zero.
The mistake becomes even more clear when setting line thickness to 99:

t=var('t')
v=plot(sin(t),-pi,pi,thickness=99)

In this case when x=0 the line is crossing 1 in the upper side and not
-1 in the lower side.

This problem occurs in all functions i have encountered so far, as if
the function is displayed 1 or 2 pixels off. It's even worse when
plotting arrows:

plot(arrow((0,0), (2,3)))

Here the arrow is clearly not starting in (0,0) as it should.

Is there a solution for this kind of problem?

Jason Grout

unread,
Nov 8, 2010, 8:37:22 PM11/8/10
to sage-s...@googlegroups.com

Yes. It's a tradeoff between sharper graphics and rounding issues with
pixels in plots. IIRC, the basic issue is that horizontal and vertical
lines are "snapped" to the nearest pixel, so that they aren't
anti-aliased and fuzzy.

This has been investigated quite a bit at:

http://trac.sagemath.org/sage_trac/ticket/7808

In short, you can do:

import matplotlib
matplotlib.rcParams['path.snap'] = False

This will make horizontal and vertical lines (like the axes) not snap to
the nearest pixel. Things may be a bit fuzzier, though.

Thanks,

Jason

Karsten

unread,
Nov 9, 2010, 12:46:51 AM11/9/10
to sage-support
Thanks! This corrects plotting the sine and cosine functions.
But there is no difference when plotting arrows, except the fuzzier
axes you mentioned.
Any ideas about that one?

I really prefer plotting to look as it should with fuzzier axes since
otherwise sage can not be used to present graphs for other people.

Jason Grout

unread,
Nov 9, 2010, 1:17:27 AM11/9/10
to sage-s...@googlegroups.com
On 11/8/10 11:46 PM, Karsten wrote:
> Thanks! This corrects plotting the sine and cosine functions.
> But there is no difference when plotting arrows, except the fuzzier
> axes you mentioned.
> Any ideas about that one?
>

All arrows are automatically shortened by a full line width on each side
so that you can draw arrows between lines and the arrow will just touch
the lines. Perhaps this decision should be revisited.


> I really prefer plotting to look as it should with fuzzier axes since
> otherwise sage can not be used to present graphs for other people.
>

Recently this capability became easy, so it should be put up for vote at
this point.

Thanks,

Jason

Karsten

unread,
Nov 9, 2010, 1:20:30 AM11/9/10
to sage-support
I just tested the following:
plot(arrow((-0.03,-0.03),(6,6)))
which "corrects" the problem and makes it seem as if the arrow
actually starts from (0,0).
Is this intended?

Karsten

unread,
Nov 9, 2010, 6:26:22 AM11/9/10
to sage-support
Just as a note I have found that the problem only occurs when it is
printed as png. Saving the plot as pdf works, and that is good enough
for including in latex.
But thanks for explaining.

Jason Grout

unread,
Nov 9, 2010, 6:34:29 AM11/9/10
to sage-s...@googlegroups.com

Well, then that is troubling, since the png and pdf outputs should be
the same. I see the same thing when I save to png or pdf. Can you give
an example command where you get different results?

Jason


Karsten

unread,
Nov 9, 2010, 8:38:28 AM11/9/10
to sage-support
One example:

t=var('t')
a=plot(sin(t),t,-pi,pi)
a.save('test.pdf')
a.save('test.png')

In the pdf the function looks "better", since it seems to go through
(0,0) which is not the case in the png.
It is even more clear to the eye when adding extra thickness to the
plot:

t=var('t')
b=plot(sin(t),t,-pi,pi,thickness=2)
b.save('test1.pdf')
b.save('test1.png')

But then the function seems to be positive in t=-pi and negative in
t=pi because of the way the beginning and end is drawn graphically. So
by keeping thickness to max 1 and saving as pdf the plot is ok.
Just a small question: Is there any reason why the end of the function
is rounded while the beginning is not?

Jason Grout

unread,
Nov 9, 2010, 10:12:14 AM11/9/10
to sage-s...@googlegroups.com
On 11/9/10 7:38 AM, Karsten wrote:
> One example:
>
> t=var('t')
> a=plot(sin(t),t,-pi,pi)
> a.save('test.pdf')
> a.save('test.png')
>
> In the pdf the function looks "better", since it seems to go through
> (0,0) which is not the case in the png.


Ah, yes. Remember how we discussed how horizontal and vertical lines
weren't quite true because they snapped to the pixels? Well, there
aren't pixels in vector graphics like pdf, so no rounding/snapping is
done, and everything is accurate.

> It is even more clear to the eye when adding extra thickness to the
> plot:
>
> t=var('t')
> b=plot(sin(t),t,-pi,pi,thickness=2)
> b.save('test1.pdf')
> b.save('test1.png')
>
> But then the function seems to be positive in t=-pi and negative in
> t=pi because of the way the beginning and end is drawn graphically. So
> by keeping thickness to max 1 and saving as pdf the plot is ok.
> Just a small question: Is there any reason why the end of the function
> is rounded while the beginning is not?
>

The function is square at both the beginning and end, at least in my
pdf. The function is drawn with capstyle="projecting", which means that
the endpoint of the curve is the center of the final square in the line.
Here is an explanation of the three types of ends ("caps") on a line:

https://developer.mozilla.org/en/SVG/Tutorial/Fill_Stroke_and_Gradients#Stroke

(in that explanation, they call our "projecting" style the "square" style)

Thanks,

Jason

Reply all
Reply to author
Forward
0 new messages