ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Thu, 15 Jun 2017 15:26:10 +0200Label sides of polygonhttps://ask.sagemath.org/question/37931/label-sides-of-polygon/Is it possible to label the sides of a polygon like in the following picture by one `polygon` command? Or do I need the `text` command as well? Or do you have any other ideas?
[https://en.wikipedia.org/wiki/Right_triangle#/media/File:Rtriangle.svg](https://en.wikipedia.org/wiki/Right_triangle#/media/File:Rtriangle.svg)Tue, 13 Jun 2017 19:14:31 +0200https://ask.sagemath.org/question/37931/label-sides-of-polygon/Answer by dan_fulea for <p>Is it possible to label the sides of a polygon like in the following picture by one <code>polygon</code> command? Or do I need the <code>text</code> command as well? Or do you have any other ideas?</p>
<p><a href="https://en.wikipedia.org/wiki/Right_triangle#/media/File:Rtriangle.svg">https://en.wikipedia.org/wiki/Right_triangle#/media/File:Rtriangle.svg</a></p>
https://ask.sagemath.org/question/37931/label-sides-of-polygon/?answer=37939#post-id-37939It seems that there is no implemented solution to the issue. No problem, there is a quick solution using bare hands. (Although we can plot the polygon by the `polygon` command, there will be in the following a parallel plot of the edges...)
def plotLabelledPolygon( vertices, labels, space=0.1 ):
"""for two lists of same length,
of vertices in the real plane, A, B, C, ...
and of labels a, b, ... for AB, BC, ...
we associate a plot object consisting of the segments and the labels.
The labels are positioned corresponding to the middle of the segments,
there is some space left in between.
"""
p = plot( [] )
n = len( vertices )
if n < 3 or n != len( labels ):
return p
zVertices = []
for A in vertices:
if type(A) in ( tuple, list ): zA = A[0] + i*A[1]
elif A in CC : zA = A
else : zA = None # feel free to extend for vectors & Co...
zVertices.append( zA )
for ind in range(n):
j = ind+1 if ind+1 < n else 0
A, zA = vertices[ ind ], zVertices[ ind ]
B, zB = vertices[ j ], zVertices[ j ]
p += line( [ A, B ] )
zBA = zB - zA
if zBA == 0:
print "zA = %s and zB = %s coincide :: IGNORED" % ( zA, zB )
continue
zT = CC( zA + zBA / 2 - space * I * zBA / abs( zBA ) )
label = labels[ ind ]
p += text( '$%s$' % label, ( zT.real(), zT.imag() ) )
return p
Examples of usage:
vertices = [ (-1,0), (1,0), (0,1) ]
labels = [ 'a', 'b', 'c' ] # or simply abc
p = plotLabelledPolygon( vertices, labels )
p.axes_color( 'gray' )
p.show()
vertices = [ (0,0), (3,-3), (1,0), (3,3) ]
labels = 'abcd'
q = plotLabelledPolygon( vertices, labels, space=0.1 )
q.axes_color( 'gray' )
q.show()
(The font, the aspect, the axes, ... can be controlled in the plot object.)Wed, 14 Jun 2017 03:38:04 +0200https://ask.sagemath.org/question/37931/label-sides-of-polygon/?answer=37939#post-id-37939Comment by Thrash for <p>It seems that there is no implemented solution to the issue. No problem, there is a quick solution using bare hands. (Although we can plot the polygon by the <code>polygon</code> command, there will be in the following a parallel plot of the edges...)</p>
<pre><code>def plotLabelledPolygon( vertices, labels, space=0.1 ):
"""for two lists of same length,
of vertices in the real plane, A, B, C, ...
and of labels a, b, ... for AB, BC, ...
we associate a plot object consisting of the segments and the labels.
The labels are positioned corresponding to the middle of the segments,
there is some space left in between.
"""
p = plot( [] )
n = len( vertices )
if n < 3 or n != len( labels ):
return p
zVertices = []
for A in vertices:
if type(A) in ( tuple, list ): zA = A[0] + i*A[1]
elif A in CC : zA = A
else : zA = None # feel free to extend for vectors & Co...
zVertices.append( zA )
for ind in range(n):
j = ind+1 if ind+1 < n else 0
A, zA = vertices[ ind ], zVertices[ ind ]
B, zB = vertices[ j ], zVertices[ j ]
p += line( [ A, B ] )
zBA = zB - zA
if zBA == 0:
print "zA = %s and zB = %s coincide :: IGNORED" % ( zA, zB )
continue
zT = CC( zA + zBA / 2 - space * I * zBA / abs( zBA ) )
label = labels[ ind ]
p += text( '$%s$' % label, ( zT.real(), zT.imag() ) )
return p
</code></pre>
<p>Examples of usage:</p>
<pre><code>vertices = [ (-1,0), (1,0), (0,1) ]
labels = [ 'a', 'b', 'c' ] # or simply abc
p = plotLabelledPolygon( vertices, labels )
p.axes_color( 'gray' )
p.show()
vertices = [ (0,0), (3,-3), (1,0), (3,3) ]
labels = 'abcd'
q = plotLabelledPolygon( vertices, labels, space=0.1 )
q.axes_color( 'gray' )
q.show()
</code></pre>
<p>(The font, the aspect, the axes, ... can be controlled in the plot object.)</p>
https://ask.sagemath.org/question/37931/label-sides-of-polygon/?comment=37942#post-id-37942Thank you very much!Wed, 14 Jun 2017 16:40:58 +0200https://ask.sagemath.org/question/37931/label-sides-of-polygon/?comment=37942#post-id-37942Comment by Thrash for <p>It seems that there is no implemented solution to the issue. No problem, there is a quick solution using bare hands. (Although we can plot the polygon by the <code>polygon</code> command, there will be in the following a parallel plot of the edges...)</p>
<pre><code>def plotLabelledPolygon( vertices, labels, space=0.1 ):
"""for two lists of same length,
of vertices in the real plane, A, B, C, ...
and of labels a, b, ... for AB, BC, ...
we associate a plot object consisting of the segments and the labels.
The labels are positioned corresponding to the middle of the segments,
there is some space left in between.
"""
p = plot( [] )
n = len( vertices )
if n < 3 or n != len( labels ):
return p
zVertices = []
for A in vertices:
if type(A) in ( tuple, list ): zA = A[0] + i*A[1]
elif A in CC : zA = A
else : zA = None # feel free to extend for vectors & Co...
zVertices.append( zA )
for ind in range(n):
j = ind+1 if ind+1 < n else 0
A, zA = vertices[ ind ], zVertices[ ind ]
B, zB = vertices[ j ], zVertices[ j ]
p += line( [ A, B ] )
zBA = zB - zA
if zBA == 0:
print "zA = %s and zB = %s coincide :: IGNORED" % ( zA, zB )
continue
zT = CC( zA + zBA / 2 - space * I * zBA / abs( zBA ) )
label = labels[ ind ]
p += text( '$%s$' % label, ( zT.real(), zT.imag() ) )
return p
</code></pre>
<p>Examples of usage:</p>
<pre><code>vertices = [ (-1,0), (1,0), (0,1) ]
labels = [ 'a', 'b', 'c' ] # or simply abc
p = plotLabelledPolygon( vertices, labels )
p.axes_color( 'gray' )
p.show()
vertices = [ (0,0), (3,-3), (1,0), (3,3) ]
labels = 'abcd'
q = plotLabelledPolygon( vertices, labels, space=0.1 )
q.axes_color( 'gray' )
q.show()
</code></pre>
<p>(The font, the aspect, the axes, ... can be controlled in the plot object.)</p>
https://ask.sagemath.org/question/37931/label-sides-of-polygon/?comment=37950#post-id-37950What if I want to label the sides by their lengths, especially if they are fractions? How can I output pretty fractions instead of the slash?
[See at the very end
Replacing `'a'` by `'\\frac{1}{2}'` (two backslashes) or by `r'\frac{1}{2}'` somehow works although it doesn't look very pretty, but it can be improved by adjusting the fontsize (within the `text` command). Is this the right way?
Alternatively, you can replace `'$%s$' % label` by `'$%s$' % latex(label)`. Then you can write fractions like 1/2 directly into the `labels` variable.]
The easiest way for that special purpose: Replace `'$%s$' % label` by `'$%s$' % latex(abs( zBA ))`.Thu, 15 Jun 2017 15:26:10 +0200https://ask.sagemath.org/question/37931/label-sides-of-polygon/?comment=37950#post-id-37950