It was a simple test with circles and hexagons

It is a spaguetti code, for testing this library with some MARIO2 project visualizations.

The results
Testing

Code:

import cairo
import math

    
WIDTH = 6
HEIGHT = 5
PIXEL_SCALE = 100


surface = cairo.ImageSurface(cairo.FORMAT_RGB24,
                             WIDTH*PIXEL_SCALE,
                             HEIGHT*PIXEL_SCALE)

ctx = cairo.Context (surface)

ctx.set_source_rgb(1,1,1)
ctx.rectangle(0,0,WIDTH*PIXEL_SCALE,HEIGHT*PIXEL_SCALE)
ctx.fill()


D = 20 
# diameter of hexagon in pixels
shift_x = (math.sqrt(3)*D/2., 0) 
# vectorial distance to next hexagon in row
shift_y = (math.sqrt(3)*D/4., 3*D/4.) 
# vectorial distance to hexagon in next row
side_fields = 3 
# number of fields along each side
width = int((2*side_fields-1)*math.sqrt(3)*D/2.+3*D/4.)+1 
# with of surface plus some border in pixels
height = int((2*side_fields-1)*3*D/4.+2*D)+1 
# with of surface plus some border in pixels


field_colors = ((1,1,1), (0,0,0), (1,0,0))
p = (
    (math.sqrt(3)*D/4., D/4.),
    (0, D/2.),
    (-math.sqrt(3)*D/4., D/4.),
    (-math.sqrt(3)*D/4., -D/4.),
    (0, -D/2.),
    (math.sqrt(3)*D/4.,-D/4.)
)


# def hexagon(ctx,color):
#     for pair in p:
#         ctx.line_to(pair[0],pair[1])
#     ctx.close_path()
#     ctx.set_source_rgb(0,0,0)
#     ctx.stroke_preserve()
#     ctx.set_source_rgb(*field_colors[color%3])
#     ctx.fill()
    
# counterHex = 10
# fields_in_line = side_fields
# increment, decreasing = 1, 0
# ctx.translate((side_fields-1)*math.sqrt(3)*D/4.,D)
# for j in range(2*side_fields-1):
#     if fields_in_line > 2*side_fields-2: increment = -1
#     for i in range(fields_in_line):
#         ctx.translate(shift_x[0],shift_x[1])
#         hexagon(ctx,i+j+decreasing)
#         counterHex -= 1
#         if counterHex==0:
#             break
#     if counterHex==0:
#             break
#     ctx.translate(-fields_in_line*shift_x[0],-fields_in_line*shift_x[1])
#     ctx.translate(-increment*shift_y[0],shift_y[1])
#     if increment == -1:
#         decreasing += 1
#     fields_in_line += increment

# =============================================================================
# BORDE CIRCULO
# =============================================================================
rb = 25
cx,cy= 330,160
ctx.save()
ctx.set_source_rgba(0.1,0.8,0.7,0.7)
ctx.arc(330, 160, rb, 0, 2*math.pi)
# ctx.fill_preserve()
ctx.restore()
ctx.save()
ctx.set_source_rgb(1,0,0)
ctx.stroke()
ctx.restore()


# =============================================================================
# Texto lado circulo
# =============================================================================
def on_draw(cx,cy, wid, cr,texto):
            
    cr.select_font_face("Serif", cairo.FONT_SLANT_NORMAL, 
        cairo.FONT_WEIGHT_BOLD)
    cr.set_font_size(wid)
    
    cr.set_source_rgb(.5, .5, .5)
    cr.move_to(cx, cy)
    cr.show_text(texto)
    
    cr.set_source_rgb(0, 0, 0)
    cr.move_to(cx+1, cy-1)
    cr.show_text(texto)
    cr.fill()
by = rb*math.sin(math.pi/4)  
on_draw(cx+rb/2,cy-by-(30*3.5/10),30,ctx,"3")    


# =============================================================================
# Hexagono en el centro
# =============================================================================
def hexagon(ctx,color):
    for pair in p:
        ctx.line_to(pair[0],pair[1])
    ctx.close_path()
    ctx.set_source_rgb(0,0,0)
    ctx.stroke_preserve()
    ctx.set_source_rgb(*color)
    ctx.fill()

green = (0,1,0)    
ctx.save()
ctx.translate(cx-shift_y[0],cy-shift_y[0]/2)
hexagon(ctx,green)
ctx.restore()

ctx.save()
green2 = (0.8,1,0.2)    
ctx.translate(cx+shift_x[0]-shift_y[0],cy-shift_y[0]/2)
hexagon(ctx,green2)
ctx.restore()


ctx.save()
green4 = (0.8,0.5,1.)    
ctx.translate(cx+shift_y[0]-shift_y[0],cy+shift_y[1]-shift_y[0]/2)
hexagon(ctx,green4)
ctx.restore()



# =============================================================================
# BORDE CIRCULO
# =============================================================================
br2 = 15
cx2,cy2= 130,360
ctx.save()
ctx.set_source_rgba(0.1,0.8,0.7,0.7)
ctx.arc(cx2, cy2, br2, 0, 2*math.pi)
# ctx.fill_preserve()
ctx.restore()
ctx.save()
ctx.set_source_rgb(0,0,0)
ctx.stroke()
ctx.restore()

br2 = 16
cx2,cy2= 130,360
ctx.save()
ctx.arc(cx2, cy2, br2, 0, 2*math.pi)
ctx.restore()
ctx.save()
ctx.set_line_width(2.1)
ctx.set_source_rgb(.5,.5,.5)
ctx.stroke()
ctx.restore()



# =============================================================================
# Draw edge
# =============================================================================
by2 = br2*math.sin(math.pi/4)  
by = rb*math.sin(math.pi/4)  
ctx.move_to(cx2+br2, cy2-by2)
ctx.line_to(cx-by, cy+by)
ctx.set_source_rgb(1, 0, 0)
ctx.set_line_width(1.16)
ctx.stroke()

green = (0,1,0)    
ctx.save()
ctx.translate(cx2,cy2)
hexagon(ctx,green)
ctx.restore()
on_draw(cx2,cy2-by2-(20*3.5/10),20,ctx,"0") 

### DRAW NUMBER inside hexagon
on_draw(cx2-shift_y[0]/1.8,cy2+shift_y[0]/1.5,15,ctx,"1") 


# =============================================================================
# DRAW USER
# =============================================================================
cx2,cy2= 130,360
brU = 5
ctx.set_source_rgb(*green)
ctx.arc(cx2-br2, cy2+br2+5, brU, 0, 2*math.pi)
ctx.fill()
ctx.set_source_rgb(0,0,0)
ctx.stroke()
ctx.fill()




surface.write_to_png('line.png')