Related
I want to plot the following data(which is stored in "0-time.txt")
time_,value
23:59:58,1
23:59:59,2
00:00:00,3
00:00:01,4
00:00:02,5
00:00:03,6
00:00:04,7
00:00:05,8
00:00:06,9
00:00:07,10
00:00:08,11
00:00:09,12
by the following gnuplot script:
set term png size 800,600
set output "0-time.png"
set datafile separator comma
set grid
set x2tics 6
set mx2tics 3
set link x2
set autoscale xfix
set autoscale x2fix
plot "0-time.txt" skip 1 every 2 using ($0*2):(0):xticlabels(int
($0*2)%6==0 ? stringcolumn(1):''), "" using ($0):2 axes x1y1 title columnheader(2)
set output
The output plot is alright except that labels on x2-axis is wrong. Please see the attached figure. How to correct it?
Maybe something like this?
Code: (a bit cleaned up)
### special tics
reset session
$Data <<EOD
23:59:58,1
23:59:59,2
00:00:00,3
00:00:01,4
00:00:02,5
00:00:03,6
00:00:04,7
00:00:05,8
00:00:06,9
00:00:07,10
00:00:08,11
00:00:09,12
EOD
set term png size 800,600
set output "0-time.png"
set datafile separator comma
set grid
set xtics 2
set mxtics 3
set link x2
set x2tics
set autoscale xfix
set autoscale x2fix
plot \
$Data using ($0*2):(NaN):xtic(int($0)%3==0?strcol(1):"") every 2 notitle, \
"" using 0:2:x2tic(int($0+1)%6==1?strcol(2):"") w p pt 7 ps 2 lc rgb "red" notitle
set output
### end of code
Result:
In Gnuplot, the data index $0 starts with zero, which is why you see 0 as the first x2 tic. But you can change the link in this way
set link x2 via x+1 inverse x-1
and then the x2 axis will be shifted by one unit with respect to x. Then you just change which x2 tics to display,
set x2tics 1, 6
which will hide 0, 6, 12, etc and show 1, 7, 13, etc instead.
How can I make a plot with some values of delta_x and delta_y positions; where I need to use palette (or colorbars) for each point showing their respective epochs (My current plot, and an example of the plot that I would like to make are shown below).
My current Gnuplot code is as follows:
set fontpath '/System/Library/Fonts'
set term post color enh eps font "Helvetica" 14
#Gnuplot script file for plotting data
#Set Line style
set style line 12 lw 1 ps 1 pt 8 # empty triangle
set style line 13 lw 1 ps 0.7 pt 81 #empty circle
#Add Legend
set key top right box
# set plot
set xrange[1.2:0]
set xlabel "Relative R.A. (mas)" # set xlabel
set mxtics 4
set xtics 0, 0.1, 1.2
set yrange[0:1]
set ylabel "Relative decl. (mas)"
set mytics 4
set ytics 0, 0.1, 1
plot "MOD1.dat" using 1:2 w points ls 13 lc rgb 'black' title "Data1", "MOD2.dat" using 1:2 w points ls 12 lc rgb 'gray' title "Data2"
Where my data are as follows:
Data1:
#Year RA(mas) DEC(mas)
1993-06-26 0.36315 0.23913
1993-12-16 0.33392 0.28443
1994-01-28 0.34606 0.30810
1994-12-23 0.37139 0.32989
1995-02-12 0.34050 0.29165
1995-08-17 0.55405 0.42913
1995-12-18 0.36928 0.2777
1996-04-07 0.49601 0.31533
1996-12-13 0.43557 0.34637
1997-11-14 0.36811 0.25562
1998-06-02 0.55603 0.36268
1998-12-07 0.52873 0.23110
2000-11-12 0.45839 0.22572
ieData2:
#Year RA(mas) DEC(mas)
1993-06-26 0.63633 0.44645
1993-09-18 0.63548 0.35586
1993-12-16 0.63161 0.41704
1994-01-28 0.27266 0.47256
1994-03-14 0.75819 0.65255
1994-04-21 0.69664 0.68481
1994-06-21 0.78735 0.72865
1994-08-29 0.91143 0.78274
1994-10-30 0.55326 0.43258
1994-12-23 0.67065 0.54423
1995-02-12 0.55778 0.51656
1995-08-17 1.01458 0.50502
Thank you.
try the palette linetype, like this:
plot 'MOD1.dat' u 2:3:1 w p pt 7 ps 2 lt palette
I am using the 32-bit version of GNUPlot in a Window 7 "Professional" OS Environment (...sadly!) and I want to do a "stack-plot" of boxes using ONLY ONE x-axis for ALL which is "TIME" in the format of a series of "Dates".
ALL of the GNUPlot Code works but, each of the plots uses its own individual x-axis which consumes a lot of graphing real estate.
I also need to be able to have variable y-axis scales for each of the stacked-plots...
Here is the "labeled" (CSV) data file:
Date,Time,Weight(kg),Height(cm),BMI,BP Max.(mmHg),BP Min.(mmHg),P/min,% Fat 09/09/2015,13:16:00,77.4,171,26.5,121,73,75,22.5 16/07/2015,09:14:34,76.9,170,26.6,111,70,76,23.5 26/06/2015,18:14:48,76.9,170,26.6,123,72,78,23.2 19/06/2015,08:45:42,77,172,26,96,60,89,22.1 15/06/2015,12:29:48,77.7,170,26.9,117,73,87,23.6 15/06/2015,12:15:58,77.8,170,26.9,127,76,77,23.7 15/06/2015,12:11:05,77.7,171,26.6,118,74,83,22.8 23/03/2015,16:39:55,78.6,170,27.2,119,72,78,24 20/03/2015,09:07:30,77.6,169,27.2,138,74,77,24.1 09/01/2015,14:30:00,79.2,170,27.4,114,71,75,24.1 07/10/2014,16:06:00,78.4,171,26.8,119,73,108,24.8 07/10/2014,16:08:00,78.4,170,27.1,109,72,75,25.1 15/09/2014,08:18:23,76.9,171,26.3,116,69,102,24.8 15/09/2014,09:20:27,76.7,172,25.9,132,76,91,21 04/09/2014,12:05:00,75.6,169,26.5,115,71,96,25.4 01/04/2014,11:18:00,76.2,171,26,115,69,70,22.9 19/03/2014,09:48:23,75.3,171,25.8,113,69,55,22.1 14/03/2014,10:39:29,75.6,170,26.2,108,69,78,22.5 05/03/2014,16:45:00,75.9,170,26.3,129,73,84,23.3 09/05/2013,17:31:00,74.5,171,25.5,135,75,92,21
And here is the "current" GNUPlot Code that I am using to generate the 5 stacked plots:
reset
set terminal windows size 1325, 625
set multiplot layout 5, 1 title "Individual Employee Biometric Data vs. Time"
set xlabel "DATE"
set timestamp
set key outside
set key center right
set pointsize 1.0
set grid lw 1
set timefmt "%d/%m/%Y"
set xdata time
set format x "%d/%m/%Y"
set xrange [ "09/05/2013\t0000" : "09/09/2015\t0000" ] noreverse nowriteback
set datafile sep ','
set arrow from 10.0,0 to 10.0, 0.5 lw 3
set label ' ' at 10.2,0.03
set label '(C) 2015' at 2050.0,-0.85
set border lw 2
set yrange [73.0:80.0]
set ylabel "(kg)"
plot 'K8.dat' using 1:3 title "BODY\nWEIGHT" with linespoints lw 2 lt rgb 'red'
set yrange [25.0:30.0]
set ylabel "kg/m^2"
plot 'K8.dat' using 1:5 title "BODY\nMASS\nINDEX" with linespoints lw 2 lt rgb 'green'
set yrange [50.0:150.0]
set ylabel "(mmHg)"
plot 'K8.dat' using 1:6 title "SYS" with linespoints lw 2 lt rgb 'blue', \ 'K8.dat' using 1:7 title "DIAS" with linespoints lw 2 lt rgb 'coral'
set yrange [40.0:120.0]
set ylabel "(bpm)"
plot 'K8.dat' using 1:8 title "HEART\nRATE" with linespoints lw 2 lt rgb 'purple'
set xlabel "DATE"
set yrange [15.0:30.0]
set ylabel "(%)"
plot 'K8.dat' using 1:9 title "BODY\nFAT" with linespoints lw 2 lt rgb 'orange'
PS - This code is from a previous GNUPlot routine so "excuse" the '#" commenting-out...
You can use multiplot to stack several plots on top of each other. You just have to switch off the plot borders appropriately for each, see help set border, and unset the abscissa xtics for all but the lowermost plot.
set multiplot
set origin 0.1, 0.1
set size 0.9,0.3
set xrange [a:b]
plot "first"
set origin 0.1,0.4
unset xtics
set border 2 # only plot left border
plot "second"
set origin 0.1,0.7
plot "third"
unset multi
Crucial is fixing the xrange for all plots, because after switching off the xtics for the following plots, you can't see if it is actually identical.
(too long for a comment)
Ok, I get what you mean by stacked plots now. To my knowledge, having several y-axes (more than 2) above a single x axis is not possible.
What you COULD however do is try to fake more than 2 axes by plotting all data in the roughly 30...150 range on the y(1)-axis, and all data in the 15...30 range on the y2axis. However, the lines would be all kind of overlapping and not as cleanly separated.
Another alternative would be to first normalize all data into an e.g. 0...10 range by subtracting the min value and dividing by max-min, then stacking these on top of each other by adding 0 for the first line, 10 for the second, and so on. However, you would then have to add hand-made y-axis tics (which is possible but somewhat bothersome).
Actually, here is a working template for the fancier solution I outlined above (implemented for three data sets, but can be extended to basically arbitrarily many)
reset
set datafile separator ","
inputfile = 'data0.txt'
stats inputfile using 3 name 'STATS_WEIGHT'
STATS_WEIGHT_range = STATS_WEIGHT_max - STATS_WEIGHT_min
stats inputfile using 4 name 'STATS_HEIGHT'
STATS_HEIGHT_range = STATS_HEIGHT_max - STATS_HEIGHT_min
stats inputfile using 9 name 'STATS_FAT'
STATS_FAT_range = STATS_FAT_max - STATS_FAT_min
# more stats for further data -- apparently needs to be BEFORE the date/time stuff
set timefmt "%d/%m/%Y"
set xdata time
set format x "%d/%m/%Y"
set xrange [ "09/05/2013\t0000" : "09/09/2015\t0000" ] noreverse nowriteback
# define the offset at which the fake y-axes start; decrease or increase offsetIncrease for spacing (effectively: blank labels) between 'graphs'
startYTicsOffset = 0
numberOfFakeYTicsPerData = 6
scalingFactor = 1.0/(numberOfFakeYTicsPerData - 1.0)
offsetIncrease = numberOfFakeYTicsPerData + 0.5
#to get rid of actual yrange numbering, set a dummy label that will be overwritten
set ytics ("dummy" 0)
#increase total actual yrange factor as needed for additional series
set yrange [0: 3 * offsetIncrease]
#add tics for weight, note that %.Xf prints the number with X decimals
do for[i=0:numberOfFakeYTicsPerData-1]{
set ytics add (sprintf("%.0f kg", STATS_WEIGHT_min + i * scalingFactor * STATS_WEIGHT_range) startYTicsOffset+i)
}
#add tics for height
startYTicsOffset = startYTicsOffset + offsetIncrease
do for[i=0:numberOfFakeYTicsPerData-1]{
set ytics add (sprintf("%.1f cm", STATS_HEIGHT_min + i * scalingFactor * STATS_HEIGHT_range) startYTicsOffset+i)
}
#add tics for fat - I couldn't figure out how to get gnuplot to print actual '%' character in sprintf directive (should be '%%' but doesn't appear to work)
startYTicsOffset = startYTicsOffset + offsetIncrease
do for[i=0:numberOfFakeYTicsPerData-1]{
set ytics add (sprintf("%.1f percent", STATS_FAT_min + i * scalingFactor * STATS_FAT_range) startYTicsOffset+i)
}
###### ... add further tics ...
plot inputfile using 1:( 0 * offsetIncrease + ($3 - STATS_WEIGHT_min)/ (STATS_WEIGHT_range * scalingFactor) ) w lp title "weight",\
inputfile using 1:( 1 * offsetIncrease + ($4 - STATS_HEIGHT_min)/ (STATS_HEIGHT_range * scalingFactor) ) w lp title "height",\
inputfile using 1:( 2 * offsetIncrease + ($9 - STATS_FAT_min) / (STATS_FAT_range * scalingFactor) ) w lp title "fat %"
### ... add further data ...
by the way: if you post or edit a question or an answer, try clicking the image icon above the editing window. It will open a little window where you can drag and drop images directly without needing a web hosting service. Like that:
I am currently working for a company where I have to evaluate a survey. Now do I have to make a plot of the data.
They want a table with the questions in the left column and a point in the right column with a distance to the question which symbolizes the average grade[0:4]. My first attempt is using gnuplot because I have used it before and now ran into the problem that if the length of the question(I already shortened them to a max. of 50 characters) is too long gnuplot is having problem displaying the plot correctly. The whole plot gets pushed to the right and you can't read it anymore.
My dataset looks like this
Eltern können sich über unsere Schule vielfä..., 2.2
Eltern werden über wichtige Entscheidungen inf..., 2.4
Eltern wissen über Projekte der Schule Bescheid, 2.4
Eltern erfahren Planung und Durchführung von F..., 1.5
Die Schule hat einen guten Ruf, 2.8
And here is my gnuplot file
set terminal pdfcairo enhanced font "Droid Sans,9" linewidth 4 rounded fontscale 1.0
set output "template.pdf"
set style line 80 lt rgb "#808080"
set border 3 back linestyle 80 #remove top and right border
set xtics nomirror
set ytics nomirror
set datafile sep ','
set xtics 0,1,4.
set ytics font ",4"
set xlabel "Note"
set style line 1 lc rgb "#0060AD" lt 1 lw 2 pt 7 pi -1 ps 1.0
set pointintervalbox 3
set xrange [0:4]
plot 'datafiles/adler_organisation.dat' using 2:0:ytic(1) notitle w lp ls 1
The result I currently get is
Here is an image how the rest of the evaluation looks like(made in LaTeX with datatool, loongtable and LTXtable).
Basically it is enough to fix the left margin with the command set lmargin at screen 0.5. Gnuplot isn't very good at estimating the margins based on the font type and font size. The result I get with this little change is:
Gnuplot cannot wrap long line automatically. You could use the epslatex terminal an put the labels in a \parbox with fixed length to achieve this, like with
label(s) = sprintf('\parbox{4cm}{\raggedleft %s}', s)
set ytics right
plot 'datafiles/adler_organisation.dat' using 2:0:ytic(label(strcol(1))) notitle w lp ls 1
But that would possibly give you problems getting the fonts. I haven't tried using epslatex together with Droid Sans.
As an other option you can use a python script to preprocess your datafile and insert line breaks. With the python script wraplabels.py:
from __future__ import print_function
import sys
import textwrap
with open(sys.argv[1], 'r') as f:
for line in f:
l, v = line.split(',')
print('"{}",{}'.format('\\n'.join(textwrap.wrap(l.strip(), 30)), v), end='')
and the gnuplot script
set terminal pdfcairo enhanced font "Droid Sans,9" linewidth 4 rounded fontscale 1.0
set output "template.pdf"
set style line 80 lt rgb "#808080"
set border 3 back linestyle 80 #remove top and right border
set tics nomirror
set datafile sep ','
set xtics 0,1,4.
set ytics font ",4" right
set xlabel "Note"
set style line 1 lc rgb "#0060AD" lt 1 lw 2 pt 7 pi -1 ps 1.0
set pointintervalbox 3
set xrange [0:4]
set lmargin at screen 0.3
plot '< python wraplabels.py datafiles/adler_organisation.dat' using 2:0:ytic(1) notitle w lp ls 1
you get a nice result
Been working with candlesticks on real financial data. It works great unless I have gaps in the data, which there are plenty with historical financial data.
I have had "set boxwidth 1 relative" and it works ok, it gives me a proper "width" of the candlestick in most cases. But if there is no data between 2 points the candlestick will become fatter, i.e. it extends right to fill that gap. The visual is horrible, the extension to the right is really bad.
I have tried playing with set boxwidth x absolute, but I cannot come to terms in how it is displaying. I have narrowed it down to set boxwidth 37500 absolute and have no idea why that number works, even though it has even worse problems then the set boxwidth 1 relative.
The first image is what it looks like using set boxwidth 37500 absolute. There the dates goes from 01/31/13, 02/01/13, 02/03/13, 02/04/13, 02/05/13. There is no 02/02/13:
The absolute shows a proper gap between 02/01 and 02/02 but 02/03 and 02/04 overlap for reasons I cannot explain.
The second image uses set boxwidth 1 relative. This has it mostly the way I want it. The candlesticks are adjacent and mostly right. But the gap on 02/02/13 it fattens to the right. There is also a gap on 02/09/13 where it also fattens, or possibly the 2 on either side extend to fill the gap I do not know.
How can I configure this so that all the candlesticks are the same width adjacent and gaps in the data are empty?
I googled this like crazy and no one talks about it. The few examples of candlesticks that I have found do not use "dates" but integers, totally worthless. Candlestick charts require dates per the manual.
Running Gnuplot 4.6 patchlevel 0 on Windows 7.
Thank you
PS: I should have added data here goes.
basic.csv:
2013-01-15 00:00:00,93.879000,93.949000,92.874000,93.078000
2013-01-16 00:00:00,93.079000,93.672000,92.458000,92.800000
2013-01-17 00:00:00,92.799000,95.011000,92.629000,94.616000
2013-01-18 00:00:00,94.617000,94.872000,94.157000,94.662000
2013-01-20 17:00:00,94.649000,94.820000,93.965000,94.155000
2013-01-21 00:00:00,94.159000,94.938000,93.726000,94.009000
2013-01-22 00:00:00,94.011000,94.284000,93.147000,93.231000
2013-01-23 00:00:00,93.229000,94.024000,92.793000,93.649000
2013-01-24 00:00:00,93.650000,94.715000,93.559000,94.489000
2013-01-25 00:00:00,94.490000,95.083000,94.472000,94.749000
2013-01-27 17:00:00,94.819000,95.007000,94.652000,94.834000
2013-01-28 00:00:00,94.835000,94.968000,94.082000,94.809000
2013-01-29 00:00:00,94.803000,95.330000,94.370000,95.248000
2013-01-30 00:00:00,95.245000,95.450000,94.255000,94.365000
2013-01-31 00:00:00,94.372000,95.799000,94.328000,95.714000
2013-02-01 00:00:00,95.715000,96.718000,95.457000,96.597000
2013-02-03 17:00:00,96.716000,96.777000,96.370000,96.572000
2013-02-04 00:00:00,96.574000,97.064000,95.968000,96.044000
2013-02-05 00:00:00,96.043000,97.426000,95.945000,97.131000
2013-02-06 00:00:00,97.133000,97.284000,96.092000,96.395000
2013-02-07 00:00:00,96.396000,97.023000,95.813000,96.145000
2013-02-08 00:00:00,96.146000,96.182000,95.124000,95.625000
2013-02-10 17:00:00,95.623000,95.744000,95.210000,95.339000
2013-02-11 00:00:00,95.336000,96.877000,95.168000,96.537000
2013-02-12 00:00:00,96.536000,96.719000,95.776000,96.214000
2013-02-13 00:00:00,96.216000,96.890000,96.114000,96.775000
2013-02-14 00:00:00,96.771000,96.964000,95.609000,95.621000
2013-02-15 00:00:00,95.622000,96.676000,95.521000,96.351000
absolute.plt:
reset
set border linecolor rgbcolor "yellow"
set key textcolor rgbcolor "white"
set obj 1 rectangle behind from screen 0,0 to screen 1,1
set obj 1 fillstyle solid 1.0 fillcolor rgbcolor "black"
set xdata time
set timefmt"%Y-%m-%d %H:%M:%S"
set xrange ["2013-01-15 00:00:00":"2013-02-15 23:59:59"]
set yrange [*:*]
set datafile separator ","
set palette defined (-1 'red', 1 'green')
set cbrange [-1:1]
unset colorbox
set style fill solid noborder
set boxwidth 37500 absolute
set title "AUDJPY" textcolor rgbcolor "white"
plot 'basic.csv' using 1:2:4:3:5:($5 < $2 ? -1 : 1) with candlesticks palette
relative.plt:
reset
set border linecolor rgbcolor "yellow"
set key textcolor rgbcolor "white"
set obj 1 rectangle behind from screen 0,0 to screen 1,1
set obj 1 fillstyle solid 1.0 fillcolor rgbcolor "black"
set xdata time
set timefmt"%Y-%m-%d %H:%M:%S"
set xrange ["2013-01-15 00:00:00":"2013-02-15 23:59:59"]
set yrange [*:*]
set datafile separator ","
set palette defined (-1 'red', 1 'green')
set cbrange [-1:1]
unset colorbox
set style fill solid noborder
set boxwidth 1 relative
set title "AUDJPY" textcolor rgbcolor "white"
plot 'basic.csv' using 1:2:4:3:5:($5 < $2 ? -1 : 1) with candlesticks palette
When using set boxwidth absolute, the width is given in units of the x-axis, which in the case of dates is seconds. So, a width of 37500 is 10 hours.
You could also use an explicit width in the 6th column, and switch to -2 to get an automatic box width for certain columns. That however would require you to manipulate your data file by hand.
Another point: Is it essential for you to include the hours in some data points? This is what narrows the distance of some adjacent points. You could ignore the hours, which would give you a point distance of minimum one day. To strip the hours, use strptime in the using statement:
reset
set border linecolor rgbcolor "yellow"
set key textcolor rgbcolor "white"
set obj 1 rectangle behind from screen 0,0 to screen 1,1
set obj 1 fillstyle solid 1.0 fillcolor rgbcolor "black"
set xdata time
set timefmt"%Y-%m-%d %H:%M:%S"
set xrange ["2013-01-15 00:00:00":"2013-02-15 23:59:59"]
set yrange [*:*]
set datafile separator ","
set palette defined (-1 'red', 1 'green')
set cbrange [-1:1]
unset colorbox
set style fill solid noborder
set boxwidth 60000 absolute
set title "AUDJPY" textcolor rgbcolor "white"
plot 'basic.csv' using (strptime('%Y-%m-%d', strcol(1))):2:4:3:5:($5 < $2 ? -1 : 1) with candlesticks palette
Result with 4.6.0:
Another script,
from candlestick_chart import Candle, Chart
# Add some candles
candles = [
Candle(133.520004, 133.610001, 126.760002, 129.410004),
Candle(128.889999, 131.740005, 128.429993, 131.009995),
Candle(127.720001, 131.050003, 126.379997, 126.599998),
Candle(128.360001, 131.630005, 127.860001, 130.919998),
Candle(132.429993, 132.630005, 130.229996, 132.050003),
]
# Create and display the chart
# Optional keyword arguments: title, width, height
chart = Chart(candles, title="Optional title")
# Set the chart title
chart.set_name("BTC/USDT")
# Set customs colors
chart.set_bear_color(1, 205, 254)
chart.set_bull_color(255, 107, 153)
chart.set_vol_bull_color(1, 205, 254)
chart.set_vol_bear_color(255, 107, 153)
# Set custom labels (empty string => label not displayed)
chart.set_label("highest", "ATH")
chart.set_label("lowest", "ATL")
chart.set_label("average", "")
chart.set_label("volume", "")
# Volume pane settings
chart.set_volume_pane_height(6)
chart.set_volume_pane_enabled(False)
# And, it is also responsive!
new_width = 200
new_height = 150
chart.update_size(new_width, new_height)
# By the way, did you know that you can add more candles in real-time?
chart.update_candles(candles[:3])
# Or completely replace current candles `enter code here`
chart.update_candles(candles[:3], reset=True)
chart.draw()