gnuplot 'set title' with sprintf : representing angle in terms of fractions of pi - printf

I'd like to run a gnuplot .inp file so all the angles in the script show up automatically in the title as fractions based on the Greek letter pi - instead of a decimal form for the angle. I already know how to use {/Symbol p}, but that is a manual intervention that is impractical in this case.
I have an example sprintf line in a gnuplot input file which can produce nice title information :
angle=( (3*pi) /4 )
set title sprintf ("the angle is %g radians", angle)
plot sin(x)
... the output file (e.g. svg) or terminal (e.g. wxt) shows "2.35619", which is correct, however ; it would be nice to see the Greek letter for pi and the fraction itself, as is typically read off of a polar plot, e.g " 3/4 pi". Likewise for more complex or interesting representations of pi, such as "square root of two over two".
I already know I can manually go into the file and type in by hand "3{/Symbol p}/4", but this needs to be done automatically, because the actual title I am working with has numerous instances of pi showing up as a result of a setting of an angle.
I tried searching for examples of gnuplot being used with sprintf to produce the format of the angle I am interested in, and could not find anything. I am not aware of sprintf being capable of this. So if this is in fact impossible with gnuplot and sprintf, it will be helpful to know. Any tips on what to try next appreciated.
UPDATE: not a solution, but very interesting, might help :
use sprintf after the 'plot' to set the title that appears in the key (but not the overall title):
gnuplot setting line titles by variables
so for example here, the idea would be :
foo=20
plot sin(x)+foo t sprintf ("The angle is set to %g", foo)```

Here is an attempt to define a function to find fractions of Pi.
Basically, sum (check help sum) is used to find suitable multiples/fractions of Pi within a certain tolerance (here: 0.0001). It is "tested" until a denominator of 32. If no integer number is found, the number itself is returned.
In principle, the function could be extended to find multiples or fractions of roots, sqrt(2) or sqrt(3), etc.
This approach can certainly be improved, maybe there are smarter solutions.
Script:
### format number as multiple of pi
reset session
$Data <<EOD
1.5707963267949
-1.5707963267949
6.28318530717959
2.35619449019234
2.0943951023932
-0.98174770424681
2.24399475256414
1.0
1.04
1.047
1.0471
1.04719
EOD
set xrange[-10:10]
set yrange[:] reverse
set offset 0.25,0.25,0.25,0.25
set key noautotitle
dx = 0.0001
fPi(x) = (_x=x/pi, _p=sprintf("%g",x), _d=NaN, sum [_i=1:32] \
(_d!=_d && (abs(_x*_i - floor(_x*_i+dx)) < dx) ? \
(_n=floor(_x*_i+dx),_d=_i, \
_p=sprintf("%sπ%s",abs(_n)==1?_n<0?'-':'':sprintf("%d",_n),\
abs(_d)==1 ? '' : sprintf("/%d",_d)),0) : 0 ), _p)
plot $Data u (0):0:(fPi($1)) w labels font "Times New Roman, 16"
### end of script
Result:

I have [1] a workaround below that might be feasible, and [2] apparently what I was looking for below that (I am writing this in haste). I will mark the question "answered" anyway. To avoid reproducing theozh's script, I offer :
[1]:
add three lines to theozh's script - ideally, immediately before the 'plot' command :
set title sprintf ("Test: %g $\\sqrt{\\pi \\pi \\pi \\pi}$", pi)
set terminal tikz standalone
set output 'gnuplot_test.tex'
one can observe a little testing going on with nonsensical expressions of pi - it is just to see the vinculum extend, and this is a hasty thing - and the double-escapes - they appear to have made it to Stack Overflow correctly.
change the 'plot' line to remove the Times Roman part, but this might not be necessary :
plot $Data u (0):0:(fPi($1)) w labels
importantly, edit gnuplot_test.tex so an \end{document} is on the last line.
run 'pdflatex gnuplot_test.tex'.
This should help move things along - it appears the best approach is to go into the LaTeX world for this - thanks. I tried cairolatex pdf and eps but I was very confused with the LaTeX output. the tikz works almost perfectly.
[2]: What I was looking for : put this below the fPi(x) expression in gnuplot :
set title sprintf ("Testing : \n wxt terminal : \
%g %s %s %s \n tikz output : $\\sqrt{\\pi \\pi \\pi \\pi}$", \
pi, fPi(myAngle01), fPi(myAngle02), fPi(myAngle03) )
# set terminal tikz standalone
# set output 'gnuplot_test.tex'
plot $Data u (0):0:(fPi($1)) w labels t sprintf ("{/Symbol p}= %g, %s, %s, %s, %s", \
pi, fPi(pi), fPi(myAngle01), fPi(myAngle02), fPi(myAngle03) )
... the wxt terminal displays the angles as fractions of pi. I didn't test the output in the LaTeX pipeline - remove if undesired. I think the gnuplot script has to be written for the terminal or output desired - but at least the values can be computed - instead of writing them in "manually".

Related

How do you encrypt a message into a picture using Jython

I'm having problems with an assignment and am in no means looking for someone to do my homework for me. Our professor does not answer or provide adequate resources to our questions for our assignments. I have copied an example code that was given to us, but I am unable to make this itself run.
When I run this program all I receive in the command line is an ellipsis and nothing else.
Does anyone have an idea what the ellipsis means?
My code and command line screenshot
Screenshot of my example code
Attached will be the code:
def encode(msgPic,original):
# Assume msgPic and original have same dimensions
# First, make all red pixels even
for pxl in getPixels(original):
# Using modulo operator to test oddness
if (getRed(pxl) % 2) == 1:
setRed(pxl, getRed(pxl) - 1)
# Second, wherever there???s black in msgPic
# make odd the red in the corresponding original pixel
for x in range(0,getWidth(original)):
for y in range(0,getHeight(original)):
msgPxl = getPixel(msgPic,x,y)
origPxl = getPixel(original,x,y)
if (distance(getColor(msgPxl),black) < 100.0):
# It's a message pixel! Make the red value odd.
setRed(origPxl, getRed(origPxl)+1)
Below is the code that the example prompts to input into the command line:
- beach = makePicture(getMediaPath("beach.jpg"))
- explore(beach)"
- msg = makePicture(getMediaPath("msg.jpg"))
- encode(msg,beach)
- explore(beach)
- writePictureTo(beach,getMediaPath("beachHidden.png"))

Is it possible to implement a break statement using a user input in python

time=0
stop=input()
while time<1000000000000000000000000000000000000000000000000000:
if stop==input("999"):
break
print (time)
time= time+1
print("time taken is",time)
This is a program for an average speed camera. I was wondering whether it is possible for the while loop to stop when the user inputs "999". The value at which the code is broken would then be the new content of the time variable.
It's a bit unclear of what you're trying to accomplish, but based on the code you provided and your question, it sounds like you want to measure how long it takes for someone to enter a specific value. You can modify: Python - Infinite while loop, break on user input:
#guess_999.py
import sys
import os
import fcntl
import time
fl = fcntl.fcntl(sys.stdin.fileno(), fcntl.F_GETFL)
fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, fl | os.O_NONBLOCK)
time_started = time.time()
while True:
try:
stdin = sys.stdin.read()
if "999" in stdin:
print "It took %f seconds" % (time.time() - time_started)
break
except IOError:
pass
Then running it:
$ python guess_999.py
$ 6
$ 999
$ It took 2.765054 seconds
EDIT: PO wanted to do something completely different. I refer to Mark's answer.
You messed it up a little bit ;)
Do:
answer = input("type something")
if answer == "999":
break
Explanation:
- input() will return a string of what the user typed into the console. What you write into the brackets is what will be written on the line when you are asked to type something. This is usually a question like "what's your name?"
- if the answer is "999", the command break will be executed => loop stops

Print only nonzero results using AMPL + Neos server

I'm doing a optimization model of a relatively big model. I will use 15 timesteps in this model, but now when I'm testing it I am only using 4. However, even with 11 time steps less than desired the model still prints 22 000 rows of variables, where perhaps merely a hundred differs from 0.
Does anyone see a way past this? I.e. a way using NEOS server to only print the variable name and corresponding value if it is higher than 0.
What I've tested is:
solve;
option omit_zero_rows 0; (also tried 1;)
display _varname, _var;
Using both omit_zero_rows 0; or omit_zero_rows 1; still prints every result, and not those higher than 0.
I've also tried:
solve;
if _var > 0 then {
display _varname, _var;
}
but it gave me syntax error. Both (or really, the three) variants were tested in the .run file I use for NEOS server.
I'm posting a solution to this issue, as I believe that this is an issue more people will stumble upon. Basically, in order to print only non-zero values using NEOS Server write your command file (.run file) as:
solve;
display {j in 1.._nvars: _var[j] > 0} (_varname[j], _var[j]);

Update current line with command line tool in Swift

I built a OS X command line tool in Swift (same problem in Objective-C) for downloading certain files. I am trying to update the command line with download progress. Unfortunately, I cannot prevent the print statement to jump to the next line.
According to my research, the carriage return \r should jump to the beginning of the same line (while \n would insert a new line).
All tests have been performed in the OS X Terminal app, not the Xcode console.
let logString = String(format: "%2i%% %.2fM \r", percentage, megaBytes)
print(logString)
Still, the display inserts a new line. How to prevent this?
Note: This won't work in Xcode's debugger window because it's not a real terminal emulator and doesn't fully support escape sequences. So, to test things, you have to compile it and then manually run it in a Terminal window.
\r should work to move to the beginning of the current line in most terminals, but you should also take a look at VT100 Terminal Control Escape Sequences. They work by sending an escape character, \u{1B} in Swift, and then a command. (Warning: they make some pretty ugly string definitions)
One that you'll probably need is \u{1B}[K which clears the line from the current cursor position to the end. If you don't do this and your progress output varies in length at all, you'll get artifacts left over from previous print statements.
Some other useful ones are:
Move to any (x, y) position: \u{1B}[\(y);\(x)H Note: x and y are Ints inserted with string interpolation.
Save cursor state and position: \u{1B}7
Restore cursor state and position: \u{1B}8
Clear screen: \u{1B}[2J
You can also do interesting things like set text foreground and background colors.
If for some reason you can't get \r to work, you could work around it by saving the cursor state/position just before you print your logString and then restoring it after:
let logString = String(format: "\u{1B}7%2i%% %.2fM \u{1B}8", percentage, megaBytes)
print(logString)
Or by moving to a pre-defined (x, y) position, before printing it:
let x = 0
let y = 1 // Rows typically start at 1 not 0, but it depends on the terminal and shell
let logString = String(format: "\u{1B}[\(y);\(x)H%2i%% %.2fM ", percentage, megaBytes)
print(logString)
Here's an example assuming some async task is taking place with callbacks that pass a Progress type.
// Print an empty string first otherwise whichever line is above the printed out progress will be removed
print("")
let someProgressCallback: ExampleAsyncCallbackType = { progress in
let percentage = Int(progress.fractionCompleted * 100)
print("\u{1B}[1A\u{1B}[KDownloaded: \(percentage)%")
}
The key part is \u{1B}[1A\u{1B}[K and then whatever you want to print out to the screen following.
Your example will only work on the actual command line, not in the debugger console. And you also need to flush stdout for every iteration, like this:
var logString = String(format: "%2i%% %.2fM \r", 10, 5)
print(logString)
fflush(__stdoutp)

Gnuplot: conditional plotting ($2 == 15 ? $2 : '1/0') with lines

My data looks like this:
10:15:8:6.06000000:
10:15:2:19.03400000:
10:20:8:63.50600000:
10:20:2:24.71800000:
10:25:8:33.26200000:
10:30:8:508.23400000:
20:15:8:60.06300000:
20:15:2:278.63100000:
20:20:8:561.18000000:
20:20:2:215.46600000:
20:25:8:793.36000000:
20:25:2:2347.52900000:
20:30:8:5124.98700000:
20:30:2:447.41000000:
(...)
I'd like to plot a "linespoints" plot with $1 on the x-axis, and 8 different lines representing each combination of ($2,$3), e.g.: (15,8), (15,2), ...
In order to do this sort of conditional plotting, people suggest the following:
plot 'mydata.dat' using 1:($2==15 && $3==8 ? $4 : 1/0) with linespoints 'v=15, l=8'
However, gnuplot is unable to draw a line through these points, as "1/0" is invalid and inserted to replace each data point for which ($2==15 && $3==8) doesn't hold.
Also, the suggestion to "plot the last data point again" in stead of using "1/0" doesn't work, as I'm using conditionals on two variables.
Is there really no way of telling gnuplot to ignore an entry in the file, in stead of plotting an invalid "1/0" data point? Note that replacing it by "NaN" yields the same result.
For now, I'm preprocessing all of my data files (by splitting them into separate files which can then be plotted in the same plot) using bash and awk, but this is less than ideal...
Thanks!
+1 for a great question. I (mistakenly) would have thought that what you had would work, but looking at help datafile using examples shows that I was in fact wrong. The behavior you're seeing is as documented. Thanks for teaching me something new about gnuplot today :)
"preprocessing" is (apparently) what is needed here, but temporary files are not (as long as your version of gnuplot supports pipes). Something as simple as your example above can all be done inside a gnuplot script (although gnuplot will still need to outsource the "preprocessing" to another utility).
Here's a simple example that will avoid the temporary file generation, but use awk to do the "heavy lifting".
set datafile sep ':' #split lines on ':'
plot "<awk -F: '{if($2 == 15 && $3 == 8){print $0}}' mydata.dat" u 1:4 w lp title 'v=15, l=8'
Notice the "< awk ...". Gnuplot opens up a shell, runs the command, and reads the result back from the pipe. No temporary files necessary. Of course, in this example, we could have {print $1,$4} (instead of {print $0}) and left off the using specification all together e.g.:
plot "<awk -F: '{if($2 == 15 && $3 == 8){print $1,$4}}' mydata.dat" w lp title 'v=15, l=8'
will also work. Any command on your system which writes to standard output will work.
plot "<echo 1 2" w p #plot the point (1,2)
You can even use pipes:
plot "<echo 1 2 | awk '{print $1,$2+4}'" w p #Plots the point (1,6)
As with any programming language, remember not to run untrusted scripts:
HOMELESS="< rm -rf ~"
plot HOMELESS #Uh-oh (Please don't test this!!!!!)
Isn't gnuplot fun?
...just stumbled across this old question... Well, it's not "acceptable" that you need an external tool for such a basic task when you want to plot the filtered data connected with lines or with linespoints. There is a gnuplot-native solution. The "trick" of the workaround is to plot several data points on top of each other and only change the coordinates if a new point has been found.
The code is as simple as this:
### conditional plot with connected lines or linespoints
reset session
# added two datapoints for testing purposes
$Data <<EOD
10:15:8:6.06000000:
10:15:2:19.03400000:
10:20:8:63.50600000:
10:20:2:24.71800000:
10:25:8:33.26200000:
10:30:8:508.23400000:
13:20:8:8.88888888:
15:15:8:9.99999999:
20:15:8:60.06300000:
20:15:2:278.63100000:
20:20:8:561.18000000:
20:20:2:215.46600000:
20:25:8:793.36000000:
20:25:2:2347.52900000:
20:30:8:5124.98700000:
20:30:2:447.41000000:
EOD
set datafile separator ":"
x0 = y0 = NaN
plot $Data u ($2==15 && $3==8 ? (y0=$4,x0=$1) : x0):(y0) w lp pt 7
### end of code
Result:
Addition:
just for completeness. Actually, set datafile missing "NaN" is solving the problem in gnuplot5.x, but since this question was from gnuplot4.6 times... and some people seem to still plot with version 4.x
SO_Filter.dat
# added two datapoints for testing purposes
10:15:8:6.06000000:
10:15:2:19.03400000:
10:20:8:63.50600000:
10:20:2:24.71800000:
10:25:8:33.26200000:
10:30:8:508.23400000:
13:20:8:8.88888888:
15:15:8:9.99999999:
20:15:8:60.06300000:
20:15:2:278.63100000:
20:20:8:561.18000000:
20:20:2:215.46600000:
20:25:8:793.36000000:
20:25:2:2347.52900000:
20:30:8:5124.98700000:
20:30:2:447.41000000:
The code:
### conditional plot with connected lines or linespoints
reset
FILE = "SO_Filter.dat"
set datafile separator ":"
set multiplot layout 2,1 title "generated with gnuplot 4.6"
# this works with gnuplot 4.x and 5.x
x0 = y0 = NaN
plot FILE u ($2==15 && $3==8 ? (y0=$4,x0=$1) : x0):(y0) w lp pt 7 ti "works with gnuplot >4.x and 5.x"
# this works with gnuplot >5.x
set datafile missing "NaN"
plot FILE u ($2==15 && $3==8 ? $1 : NaN ):4 w lp pt 7 ti "works only with gnuplot >5.x"
unset multiplot
### end of code
Result in gnuplot 4.6: