From 0705dd00930cd993cc97a277dfdf043775da6d3a Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 3 Apr 2022 15:27:33 +0200 Subject: Add script to interactively place rotated labels --- gnuplot.org | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/gnuplot.org b/gnuplot.org index 58e9dce..be820a4 100644 --- a/gnuplot.org +++ b/gnuplot.org @@ -26,6 +26,8 @@ set datafile missing NaN A macro to easily reset gnuplot and also reload my settings. #+begin_src gnuplot init="load '~/.gnuplot'" +before_refresh="" # Commands to eval before each refresh +r="@before_refresh;refresh" #+end_src Here is a handy function to define colors with individual rgb integers instead of the hex notation. Example usage: ~plot x w l lc rgb rgb(255,80,0)~. Alternatively gnuplot also supports hsv colors with ~hsv2rgb(h,s,v)~. @@ -37,7 +39,7 @@ When setting the column using a variable you can not use the shorthand syntax ~$ #+begin_src gnuplot c(a)=column(a) #+end_src - +* Mathematical functions A collection of functions that can calculate a running average. #+begin_src gnuplot # running averages @@ -63,6 +65,12 @@ And some derivatives functions. d(y) = ($0 == 0) ? (y1 = y, 1/0) : (y2 = y1, y1 = y, y1-y2) d2(x,y) = ($0 == 0) ? (x1 = x, y1 = y, 1/0) : (x2 = x1, x1 = x, y2 = y1, y1 = y, (y1-y2)/(x1-x2)) #+end_src + +Functions to convert between radians and degrees. +#+begin_src gnuplot +rad(deg)=deg/180*pi +deg(rad)=rad/pi*180 +#+end_src * Colors =podo= is a good standard colorblind friendly colorsequence. #+begin_src gnuplot @@ -103,7 +111,6 @@ Also set output to a =.ps= file. After that: ps2ps -sPAGESIZE=a4 yourfilename.ps new_dina4_file.ps #+end_src To finish either use something like =ps2pdf= or view the =.ps= file with =ghostview=. - * Interactive Label Placement [[http://www.gnuplotting.org/interactive-label-placing/][Source]]. I adapted the =label_loop= function to newer gnuplot syntax & added functionality for multiple arguments. The function call to @@ -111,7 +118,7 @@ added functionality for multiple arguments. The function call to macro like this: ~@iLabel "label1" "label2"~ #+begin_src gnuplot -iLabel = "call '~/git/projects/dotfiles/tangle/label_loop.gp " +iLabel = "call '~/git/projects/dotfiles/tangle/label_loop.gp' " #+end_src #+begin_src gnuplot :tangle tangle/label_loop.gp @@ -145,3 +152,59 @@ do for [ELEMENT in ARG1." ".ARG2." ".ARG3." ".ARG4." ".ARG5] { } } #+end_src + +We can also interactively place rotated labels. Getting the label rotation correct is somewhat tricky and heavily relies on macros. Also the use of ~refresh~ limits the usefulness of this for multiplots. +#+begin_src gnuplot :tangle tangle/label.gp +# label +# Script to interactively position a rotated label. +# +# To update after changing graph size rotation angles are scaled with +# the scaling() function. List of useful macros you should define: +# scaling(_)= (1.0*(GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)/(GPVAL_TERM_XMAX-GPVAL_TERM_XMIN))/((GPVAL_Y_MAX-GPVAL_Y_MIN)/(GPVAL_X_MAX-GPVAL_X_MIN)) +# label_reset= "@label_unset;@label_labels;replot;" +# label_init= "undefine label_labels label_unset" + +if (!exists("label_number")) {label_number = 1} +if (!exists("label_labels")) {label_labels = ""} +if (!exists("label_unset")) {label_unset = ""} + +do for [ELEMENT in ARG1." ".ARG2." ".ARG3." ".ARG4." ".ARG5] { + print(ELEMENT) + while (1) { + next=0 + + array pointsX[2]; array pointsY[2] + do for [point=1:2]{ + pause mouse any + if( MOUSE_BUTTON==1 ) { + pointsX[point]=MOUSE_X + pointsY[point]=MOUSE_Y + } else { next=1;break } + } + if(next){break} + if (pointsX[2] == pointsX[1]){ dx = 1e-20 } + else { dx = pointsX[2] - pointsX[1] } + dy = pointsY[2] - pointsY[1] + + cmd=sprintf("set label %i \"%s\" at %f,%f rotate by deg(atan(%f*scaling(NaN)));",\ + label_number, ELEMENT, pointsX[1], pointsY[1],dy/dx) + eval(cmd); refresh + } + print cmd + label_labels = label_labels.cmd + label_unset = label_unset.sprintf("unset label %i;", label_number) + label_number=label_number+1 +} +refresh +#+end_src + +To make using the script easier define a few macros/functions. +#+begin_src gnuplot +scaling(_)= (1.0*(GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)/(GPVAL_TERM_XMAX-GPVAL_TERM_XMIN))/((GPVAL_Y_MAX-GPVAL_Y_MIN)/(GPVAL_X_MAX-GPVAL_X_MIN)) # functions need to have at least one argument +label="call '~/git/projects/dotfiles/tangle/label.gp' " + +label_reset= "@label_unset;@label_labels;refresh;" +before_refresh = before_refresh."set output GPVAL_OUTPUT;@label_unset;@label_labels;" +label_init= "@label_unset;label_labels='';label_unset=''" +@label_init # clear labels each @init +#+end_src -- cgit v1.2.3