Skip to content

Instantly share code, notes, and snippets.

@trappitsch
Created April 26, 2023 12:01
Show Gist options
  • Save trappitsch/b14b4e7d5d90a798f1308c9f297cff4e to your computer and use it in GitHub Desktop.
Save trappitsch/b14b4e7d5d90a798f1308c9f297cff4e to your computer and use it in GitHub Desktop.
Automatic labeling of an Inkscape map

Automatic Inkscape labels

This gist describes how to automatically features in an images with labels. It is intended in the case where you have a an image, i.e., an SEM map of a sample mount and SEM stage coordinates with features that you wnat to label.

What you will need:

  • An image / map with features to map
  • A table with labels for the features and stage coordinates
  • Inkscape installed on your computer

Workflow:

  1. Install the Simple Inkscape Scripting plugin for Inkscape
  2. Import your image into Inkscape and scale it such that 1 mm in Inkscape is equal to 1 µm on your image
  3. Find three features for which you have stage coordinates on your Inkscape map and note down the Inkscape coordinates. It is recommended that these features are far apart from each other, i.e., top left, top right, and bottom center of the map.
  4. Use the CoordinateTransformation program to convert your stage coordinates into Inkscape coordinates using the three features that you identified. With three features, use the Admon routine to transform the coordinates. If your final results are not satisfactory, try adding more feature to the coordinate transformation and use the Nittler routine. For the latter to work, you will have to multiply all your stage coordinates with a factor of 1000.
  5. Export the transformed coordinates as a .csv file
  6. Use the grain_labeler.py python script with adjustments to your case (see below) with the simple inkscape scrpiting plugin.

grain_labeler.py

The following variables have to be adjusted to your case:

Note: Python is zero-indexed, which means that the first column will be column 0.

  • fname: File name for your .csv file (use absolute path)
  • hdrrows: Number of header lines in the file before the data start
  • namecol: Number which column contains the feature labels
  • xcol: Column that contains the Inkscape x-coordinates
  • ycol: Column that contains the Inkscape y-coordinates

Optional variables:

  • separator: How your data are separated in the file, should stay "," for a .csv file
  • circle_radius: Radius of the circle in Inkscape mm
  • circle_color: Color of the circle and labels as RGB code, see, e.g., here
  • circle_ew: Circle edge width in Inkscape mm
  • layer_name: Name of the Inkscape layer that will be created and where annotations will be written into
# Draw circles and write labels in inkscape
# EDIT THE FOLLOWING LINES #
# transfered coordinates file specifications
fname = "/home/reto/coordinates_transfered_inkscape.csv"
hdrrows = 1 # number of header rows
namecol = 0
xcol = 5
ycol = 6
separator = ","
# drawing parameters
circle_radius = 3
circle_color = "#FF0000"
circle_ew = 0.3
layer_name = "auto_labels"
# RUN THE LABELING - NO NEED TO EDIT (HOPEFULLY)#
# read in the coordinate file and save coordinates
with open(fname, "r") as fin:
content = fin.read().split()
name = []
xcord = []
ycord = []
for it, line in enumerate(content):
if it >= hdrrows:
splt = line.split(separator)
name.append(splt[namecol])
xcord.append(float(splt[xcol]))
ycord.append(float(splt[ycol]))
# create a new layer with the given name
lay = layer(layer_name)
for it in range(len(xcord)):
# draw the circles
lay.append(
circle(
(xcord[it] * mm, ycord[it] * mm),
circle_radius,
stroke_width=circle_ew,
stroke=circle_color,
)
)
# write the text
ymove = 4
text_pos = (xcord[it], ycord[it] + circle_radius + ymove)
lay.append(
text(
name[it], text_pos, text_anchor="middle", font_size="2pt", fill=circle_color
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment