The [[clickloc.tk]] micro-app just opens an image file and prints out
the pixel coordinates of any mouse clicks upon it. I use it to get
-rough numbers from journal figures. You can use [[scale_click.sh]] to
+rough numbers from journal figures. You can use [[scale_click.py]] to
convert the output to units of your choice, if you use your first four
clicks to mark out the coordinate system (xmin,anything),
(xmax,anything), (anything,ymin), and (anything,ymax).
$ pdfimages article.pdf fig
$ clickloc.tk fig-000.ppm > fig-000.pixels
- $ scale_click.sh 0 10 5 20 fig-000.pixels > fig-000.data
+ $ scale_click.py 0 10 5 20 fig-000.pixels > fig-000.data
Take a look at [[plotpick]] for grabbing points from raw datafiles
(which is more accurate and easier than reverse engineering images).
--- /dev/null
+#!/usr/bin/env python
+#
+# Copyright (C) 2010-2012 W. Trevor King <wking@tremily.us>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+
+"""Convert `clickloc.tk` pixel coordinates to physical coordinates
+"""
+
+from math import exp, log
+
+
+__version__ = '0.2'
+
+
+if __name__ == '__main__':
+ from argparse import ArgumentParser
+
+ parser = ArgumentParser(description=__doc__, version=__version__)
+ parser.add_argument(
+ '-x', '--logx', default=False, action='store_const', const=True,
+ help='Use a log scale for the physical abscissa')
+ parser.add_argument(
+ '-y', '--logy', default=False, action='store_const', const=True,
+ help='Use a log scale for the physical ordinate')
+ parser.add_argument(
+ dest='xmin', type=float,
+ help='Physical coordinate for the xmin-pixel pair')
+ parser.add_argument(
+ dest='xmax', type=float,
+ help='Physical coordinate for the xmax-pixel pair')
+ parser.add_argument(
+ dest='ymin', type=float,
+ help='Physical coordinate for the ymin-pixel pair')
+ parser.add_argument(
+ dest='ymax', type=float,
+ help='Physical coordinate for the ymax-pixel pair')
+ parser.add_argument(
+ dest='input',
+ help='File containing pixel coordinates')
+ args = parser.parse_args()
+
+ with open(args.input, 'r') as f:
+ # reference points in pixels from the first 4 clicks
+ xmin_p = float(f.readline().split()[0])
+ xmax_p = float(f.readline().split()[0])
+ ymin_p = float(f.readline().split()[1])
+ ymax_p = float(f.readline().split()[1])
+ loc = locals()
+ for key in ['xmin', 'xmax', 'ymin', 'ymax']:
+ loc[key] = getattr(args, key)
+ if args.logx:
+ print(('# Xp -> exp((Xp-{xmin_p})/({xmax_p}-{xmin_p})'
+ '*log({xmax}/{xmin}) + log({xmin}))').format(**loc))
+ else:
+ print(('# Xp -> ({xmax}-{xmin})/({xmax_p}-{xmin_p})'
+ '*(Xp-{xmin_p}) + {xmin}').format(**loc))
+ if args.logy:
+ print(('# Yp -> exp((Yp-{ymin_p})/({ymax_p}-{ymin_p})'
+ '*log({ymax}/{ymin}) + log({ymin}))').format(**loc))
+ else:
+ print(('# Yp -> ({ymax}-{ymin})/({ymax_p}-{ymin_p}'
+ '*(Yp-{ymin_p}) + {ymin}').format(**loc))
+
+ for line in f:
+ x_p,y_p = [float(x) for x in line.split()]
+ if args.logx:
+ x = exp(
+ (x_p - xmin_p)/(xmax_p - xmin_p)*log(xmax/xmin)
+ + log(xmin))
+ else:
+ x = (xmax - xmin)/(xmax_p - xmin_p) * (x_p - xmin_p) + xmin
+ if args.logy:
+ y = exp(
+ (y_p - ymin_p)/(ymax_p - ymin_p)*log(ymax/ymin)
+ + log(ymin))
+ else:
+ y = (ymax - ymin)/(ymax_p - ymin_p) * (y_p - ymin_p) + ymin
+ print('{}\t{}'.format(x, y))