5

I'm on German Windows 8.1 64Bit with gnuplot 4.6.5, using the svg terminal. If I plot datafiles that have big numbers, like "one million", gnuplot does not print a digit grouping sign.

For example, if my datafile has values in the order of one million, I want the numbers at the y-axis be displayed as 1.000.000 (with . being the group sign, not the decimal sign!), but gnuplot gives me just 1000000.

The option set decimalsign locale just changes the decimal sign (separator between whole number and fractional part, like 1+1/2 = 1,5 with , being the decimal sign). But neither setting decimalsign nor not calling this command at all shows digit grouping signs in the plot. I only get ugly 1000000 or 1500000 instead of 1.000.000 or 1.500.000.

I also tried

set decimal locale
set format y "%'f"

which just gives me at all tics the label "%'f", instead of the numbers! Each tic has just "%'f", again and again. It just prints the format string as is into the plot and no numbers at all. The console output is decimal_sign in locale is , which is correct for german locale, so gnuplot recognizes it correctly. In my control panel of Windows the thousand separator is set correctly to . and the decimal sign to , too.

Setting tic by tic by hand is no option. I.e. set ytics add ('1.000.000' 1e6) for dozenz of dozenz tics is no option for me.

How do I automatically get thousand separators in gnuplot?

Foo Bar
  • 1,764
  • 4
  • 24
  • 43

4 Answers4

4

That seems not to work on Windows. From the gnuplot documentation

Internationalization (locale settings): Gnuplot uses the C runtime library routine setlocale() to control locale-specific formatting of input and output number, times, and date strings. The locales available, and the level of support for locale features such as "thousands’ grouping separator", depend on the internationalization support provided by your individual machine.

And judging from questions like How can I add a thousands separator to a double in C on Windows? Printing integers with thousands separators in Windows using C it is not possible since the apostrophe in the format string is a Unix specialty and not a C standard.

I think there is no workaround to get this working on Windows with autoscaling.

For the records: The following script works fine on Linux:

set format "%'.0f"
set xrange [0:1e6]
plot x

enter image description here

Community
  • 1
  • 1
Christoph
  • 47,569
  • 8
  • 87
  • 187
  • Thanks, then it is sadly true what I already guessed. Is there any chance that such feature will be implemented somehow into gnuplot (e.g. own implementation instead of relaying on the C library)? – Foo Bar Mar 11 '14 at 19:05
  • I don't know. You could try and file a feature request at http://sourceforge.net/p/gnuplot/feature-requests/ – Christoph Mar 11 '14 at 19:15
  • Unfortunately, this does not work in 5.2 patchlevel 8 on Ubuntu 20.04. – David Georg Reichelt Jul 20 '20 at 15:18
  • 1
    Fortunately, this works adding `set decimalsign locale; set decimalsign "."` before the commands you posted (on Ubuntu 20.04, gnuplot 5.2, german locale). – David Georg Reichelt Jul 20 '20 at 15:28
2

Only ., , and are possible as separator (at least Linux). E.g. "french" gives a space:

set decimalsign locale "french"   # thousand separator becomes ` `
set decimalsign "."
set format "%'.2f";               # `'` activates the thousand separator 
pl [0:1e5] x

0

Not the most glamorous of solutions, especially if you've got a lot of tics but you could do something like

set ytics ("1.000.000" 1e6, "1.500.000" 1.5e6, etc.)

I'd be interested to hear of anything nicer!

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
  • Thanks, but this does not really work if you use autoscaling. I'm plotting a lot of similar graphs with the exact same script and don't need to adjust anything. Only the tic numbers don't work. And manually setting them is no solution in an automated setup. – Foo Bar Mar 11 '14 at 16:29
0

Just for fun and feasibilty... If you absolutely need thousand separators, you can construct a workaround for Windows (with some complexity and limitations). Tested with gnuplot 5.2.6.

Basic recipe:

  1. define a function which converts numbers into text with thousand separators.
  2. set the tic labels yourself using text with thousand separators
  3. place the tic labels by trying to "mimic" gnuplot's setting of tic labels. For this, use gnuplot's suggestions about the scaling by plotting to a dummy terminal first. For this, this post of @Christoph is very helpful.

Code:

### add thousand separators to tic labels for Windows
reset session

# settings for thousand separator
ts = "'"   # thousand separator
ThousandSeparator(a,ts) = abs(a)>=1000 ? (TS_a=sprintf("%.0f",a), TS_b=strlen(TS_a), \
    TS_c=strstrt(TS_a,'-')+1, TS_d=TS_c>1?'-':'', (sum[TS_i=TS_c:TS_b] \
    (TS_d=((TS_b-TS_i)%3==0&&(TS_i<TS_b)?TS_d.TS_a[TS_i:TS_i].ts:TS_d.TS_a[TS_i:TS_i]),\
    0), TS_d)) : sprintf("%g",a)

# settings for (auto-)tics
range(axis) = axis eq "y" ? abs(GPVAL_Y_MAX-GPVAL_Y_MIN) : abs(GPVAL_X_MAX-GPVAL_X_MIN)
power(axis) = 10.**int(sprintf("%.15e",range(axis))[strstrt(sprintf("%.15e",range(axis)),"e")+1:]) 
rangenorm(axis) =range(axis)/power(axis)
posns(axis) = 20.0 / rangenorm(axis)
tics(axis) = \
    posns(axis)>40?0.05:posns(axis)>20?0.1:posns(axis)>10?0.2:posns(axis)>4? \
    0.5:posns(axis)>2?1:posns(axis)>0.5?2:ceil(range(axis))
ticstep(axis) = tics(axis) * power(axis)

set xrange[0:1e6]
set terminal push    # save current terminal
set terminal unknown
plot x lc rgb "web-green"
set terminal pop     # restore terminal

# set xtics
do for [i=0:ceil(range("x")/ticstep("x"))+1] {
   set xtics add (ThousandSeparator(GPVAL_X_MIN+i*ticstep("x"),"'") GPVAL_X_MIN+i*ticstep("x"))
}
# set ytics
do for [i=0:ceil(range("y")/ticstep("y"))+1] {
   set ytics add (ThousandSeparator(GPVAL_Y_MIN+i*ticstep("y"),"'") GPVAL_Y_MIN+i*ticstep("y"))
}
replot
### end of code

Limitations:

if the begin of the axis (e.g. GPVAL_X_MIN) is not identical with the first tic label, the above procedure doesn't work (yet). However, I haven't yet found the value which gnuplot sets as first tic value. There seems to be no GPVAL_... variable for this. Maybe it can be extracted somehow?

Example 1: (works ok)

set xrange[0:1e6]

enter image description here

Example 2: (doesn't work, because GPVAL_X_MIN=-50000 but first tic should be at 0)

set xrange[-50000:1e6]

enter image description here

theozh
  • 22,244
  • 5
  • 28
  • 72