I've been searching for a while now to find out how to remove days of the week from a financial plot with no success.
I need the plot to just include the days of the week and completely miss out the weekends such that there is no 2-day gap in the financial chart.
I have the data in CSV format Open/Low/Close/High and it has the weekend data missing, it plots fine but I can't find how to not show the weekends, any help would be really appreciated.
I'd like to see it say M/T/W/T/F/M/T/W/T/F on the X basically rather than M/T/W/T/F/S/S/M etc...
Cheers,
Chris.
As far as I know, this cannot be done with gnuplot itself - you need to bring the file into the desired shape before. If you are on Linux, this can be done with something like
awk '{if( index( $1, "S" ) == 0 ) print $0 >> "new.dat"}' old.dat
where old.dat is your original file and new.dat the new file without weekends. I have assumed here that your data file has the weekday as the first entry in each line.
This would work under Windows as well, but you would need to install Gawk for Windows first.
The data is not shown in the file, the file is just weekday based and misses the weekends. If you plot the data you get these 2day gaps at the weekend so I want to remove these gaps. It's more really to do with the x axis having weekends in to make it linear.
Here is an example of part of the file:
2006-03-23T16:59 1.7470 1.7324 1.7471 1.7344 0.0000 0.0000 0.0000 0.0000
2006-03-24T16:59 1.7346 1.7308 1.7441 1.7428 0.0000 0.0000 0.0000 0.0000
2006-03-27T17:59 1.7424 1.7415 1.7492 1.7459 0.0000 0.0000 0.0000 0.0000
2006-03-28T17:59 1.7462 1.7422 1.7537 1.7424 0.0000 0.0000 0.0000 0.0000
If you look at the dates, there are gaps in the file. There should be gaps because these days have no data. The graph however should run without gaps and that is what I am trying to achieve.
I just came across set xdtics today. I doubt you're still working on this, but maybe that will be helpful for someone else... (see help xdtics)
Assuming your data file isn't missing any weekdays, you can treat the date column as a string type. (If you're missing weekdays, your chart will skip over those dates without allocating any space for them, which is easy to miss, so beware.)
I have a date as the first column in my data file in YYYY-MM-DD format. The data I'm plotting is in the second column. Here are the relevant lines of my gnuplot configuration:
set format x '%s'
plot 'file' using 0:2:xtic(substr(strcol(1),6,10))
The set format line tells gnuplot how to print the x labels. The using config uses column 0 (the index) as the x parameter, column 2 (the data) as the y parameter, and provides special instructions for printing labels: only print characters 6–10. (This chops off the year portion, which helps the label fit without overlapping in my case.)
Also see this SO answer. I wouldn't want to replicate this "broken axis" solution for every weekend, but perhaps it could serve to inspire.
If you want to neglect the weekends on the time scale you can simply define a function which returns the day number after time(0) omitting the weekends. Note, that time(0) is 1970-01-01 00:00:00 for gnuplot 5.x and 2000-01-01 00:00:00 for gnuplot 4.x.
dw5(t) returns day number after time(0) omitting the weekends and NaN if t is a weekend day.
dw5tow7(n) returns the date from the "5-day-week" day number and NaN if input is NaN.
dw7Tic(n) returns the date label for xtic and empty string '' if input is NaN.
For example, the command:
do for [i=0:10] { print sprintf("%s % 4d",strftime("%Y-%m-%d",dw5tow7(i)),i) }
will return in gnuplot5.x:
1970-01-01 0
1970-01-02 1
1970-01-05 2
1970-01-06 3
1970-01-07 4
1970-01-08 5
1970-01-09 6
1970-01-12 7
1970-01-13 8
1970-01-14 9
1970-01-15 10
Script: (works for gnuplot>=5.0.0, Jan. 2015)
### remove weekends on time scale
reset
FILE = "SO9680677.dat"
# create some random test data
set print FILE
t0 = time(0)
y0 = 100
do for [i=0:60] {
t = t0 + i*3600*24
if (int(tm_wday(t)+1)%7>1) {
print sprintf("%s %g",strftime("%Y-%m-%d",t),y0=y0+rand(0)*1-0.5)
}
}
set print
SecPerDay = 3600*24
SecPerWeek = 7*SecPerDay
isWeekend(t) = int(tm_wday(t)+1)%7 < 2
myTimeFmt = "%Y\n%m-%d"
tOff = tm_year(0)==1970 ? 3 : 5 # offset gnuplot5.x: 3, gnuplot4.x: 5
dw5(t) = isWeekend(t) ? NaN : int(t/SecPerDay) - 2*int((t+tOff*SecPerDay)/SecPerWeek)
dw5tow7(n) = n==n ? n*SecPerDay + (int(n+tOff)/5)*2*SecPerDay : NaN
dw7Tic(n) = n==n ? strftime(myTimeFmt,dw5tow7(n)) : ''
set key top center out noautotitle
set grid x,y
set ytics 1
set multiplot layout 2,1
set xrange[:] noextend
set format x myTimeFmt timedate
plot FILE u (timecolumn(1,"%Y-%m-%d")):2 w lp pt 7 lc rgb "red" ti "with weekends"
set format x "%g\n" numeric
plot FILE u (dw5(timecolumn(1,"%Y-%m-%d"))):2 w lp pt 7 lc rgb "web-green" ti "without weekends", \
'' u (t0=dw5(timecolumn(1,"%Y-%m-%d"))):(NaN):xtic(dw7Tic(t0)) every 5
unset multiplot
### end of script
Replace the above multiplot section with the snippet below and the script will run with gnuplot>=4.6.0 (March 2012). Maybe with further tweaking it can be made work with gnuplot 4.4.0.
### version for gnuplot 4.6.0, March 2012
set multiplot layout 2,1
set timefmt "%Y-%m-%d"
set xdata time
set format x myTimeFmt
plot FILE u 1:2 w lp pt 7 lc rgb "red" ti "with weekeends"
set format x "%g\n"
plot FILE u (dw5(timecolumn(1))):2 w lp pt 7 lc rgb "web-green" ti "without weekends", \
'' u (t0=dw5(timecolumn(1))):(NaN):xtic(dw7Tic(t0)) every 5 w p
unset multiplot
Result:
Actually, after all, the larger your time range the less you will notice if there are weekends or not.
Using some external tool (I would wrote a bash or python script for that, I believe; it should not be difficult), you can insert lines for weekend days (one line for a day) into your data file, like this:
2006-03-26T00:00 NaN NaN NaN NaN NaN NaN NaN NaN
(or you can just append those NaNs for weekends at the end of data file and use unique keyword)
and then plot, let's say, the first data with using 1:($2) with linespoints, not using 1:2 ...
This should work for you.
Related
I've got a data file with daily values for the amount of rain in the 4th column, for each day of the year.
I'd like to plot a bar graph with each month in the x-axis, and the total monthly amount of rain in the y-axis: that is, to plot "January" (with %B or %b format) vs the sum of the 31 first values of the 4th column. Then to plot "February" vs the sum of the next 28 values of the 4th column, and so on. Do you know how to do that with gnuplot ? Besides, is it possible to write the numerical value of the monthly amounts of rain, on top of each bar ?
I can imagine and understand that for a gnuplot beginner it will not be easy to find and combine the necessary commands to realize your task. If you do a search you will most probably not find exactly your case, but there should be very similar questions and examples around. The key search would be "creating a histogram".
Check help smooth frequency, help strftime, help strptime, help datablocks, help table, basically for every command or keyword there should be a help entry.
The following example is one way to achieve what you are asking for. It is basically binning data, like creating a histogram. Here, your bins will be the months in the following numerical format, e.g. 202109, 202110, 202111, 202112, 202201, etc.
In the example below, some random test data (mm of rain per day) will be created in order to illustrate the result with a graph.
Example data in $Data:
2021-12-01 66
2021-12-02 0
2021-12-03 0
2021-12-04 17
2021-12-05 52
Plot your data into a datablock $Monthly using the option smooth frequency. It will sum up all values per month.
The result in $Monthly will be something like this:
202107 368
202108 622
202109 557
202110 361
202111 628
I hope you can adapt the code to your data and needs.
Edit: the previous version of the code used the plotting style with boxes for the monthly plot. However, this style is centering the box at the beginning of the month, which is undesired here (especially when plotting together with the daily rain). The modified code is using the plotting style with boxxyerror which plots the boxes from the beginning of the month to the beginning of the next month. Check help boxes and help boxxyerror.
Code:
### sum up monthly rainfall
reset session
TimeFmtInput = "%Y-%m-%d"
# create some random test data
set print $Data
StartDate = strptime(TimeFmtInput,"2021-04-01")
do for [i=0:280] {
RainMM = int(rand(0)+0.3) * rand(0)*100
print sprintf("%s %.0f",strftime(TimeFmtInput,StartDate+3600*24*i),RainMM)
}
set print
set table $Monthly
plot $Data u (tm_year(timecolumn(1,TimeFmtInput))*100+tm_mon(timecolumn(1,TimeFmtInput))+1):2 smooth freq
unset table
set style fill solid 0.3
set format x "%Y\n%b" timedate
set key out top center
set grid x,y
set xtics out
NextMonth(t) = strptime("%Y%m",sprintf("%04d%02d",tm_year(t),tm_mon(t)+2))
NextDay(t) = t + 24*3600
set multiplot layout 2,1
plot $Data u (t0=timecolumn(1,TimeFmtInput)):2:(t0):(NextDay(t0)):(0):2 w boxxy lc "blue" title "Daily rain / mm"
set xrange[GPVAL_X_MIN:GPVAL_X_MAX] # take the same xrange as the previous plot
plot $Monthly u (t0=timecolumn(1,"%Y%m")):2:(t0):(NextMonth(t0)):(0):2 w boxxy lc "blue" title "Monthly rain / mm"
unset multiplot
### end of code
Result:
How do I plot this time samples with a string (W) inside (column 3) ?
And How do I control xtics increment with time format ?
Few lines of Data :
France,FR,2020-W09,118,3318,67012883,4.95128675481698,3.55635925256178,TESSy
France,FR,2020-W10,996,11101,67012883,16.5654714482288,8.97216466984956,TESSy
France,FR,2020-W11,4297,29623,67012883,44.2049329529667,14.5056206326166,TESSy
France,FR,2020-W12,10595,73235,67012883,109.28495644636,14.4671263740015,TESSy
France,FR,2020-W13,24156,122870,67012883,183.35280396756,19.6598030438675,TESSy
France,FR,2020-W14,30304,127029,67012883,189.55907329043,23.8559698966378,TESSy
France,FR,2020-W15,24925,140316,67012883,209.386604065371,17.7634767239659,TESSy
My script :
#https://www.ecdc.europa.eu/en/publications-data/covid-19-testing
#Data (105,77K) here :
system("wget https://opendata.ecdc.europa.eu/covid19/testing/csv -P $PWD -O testing.csv")
reset
set term wxt font ',11' size 1200,800
set datafile separator ","
set grid
#set key at screen 0.9, 0.9
timefmt = "%Y-%s%W"
set xdata time
set xtics format timefmt timedate rotate by -45
SECPERWEEK = 3600.*24.*7.
Y_W(col) = timecolumn(col,timefmt) + SECPERWEEK * (strcol(col)[2:3] - 1)
plot '< grep France testing.csv' u (Y_W(3)):4 notitle w l
Thank you
Here is a suggestion how I would do it. It's maybe not obvious and looks maybe a bit complicated, but it is a gnuplot-only solution.
Since I do not run Linux, I do not have grep, that's why I define myFilter() in gnuplot itself which is platform independent.
Everytime this filter gives a hit, the counter t will be increased by one which has the advantage that the data can contain a interlaced mix of countries. I assume that's what grep would allow as well. The only assumption here is that the week numbers are in (ascending) order, they would not be sorted.
I guess here it is not necessary to have the x-axis as timeformat.
The situation would be different if there are missing calendar week(s) and you want to keep an according gap for them.
With myOffset=0 and myEvery=2 you set how many x-tic labels you want to have displayed.
There is certainly room for improvement and I'm sure there are other solutions... so, just as a starting point...
Code:
### plot filtered data with custom xtics
reset session
$Data <<EOD
France,FR,2020-W09,118,3318,67012883,4.95128675481698,3.55635925256178,TESSy
France,FR,2020-W10,996,11101,67012883,16.5654714482288,8.97216466984956,TESSy
France,FR,2020-W11,4297,29623,67012883,44.2049329529667,14.5056206326166,TESSy
Luxembourg,LU,2020-W11,11,222,33333333,44.4444444444444,55.5555555555555,fghij
Luxembourg,LU,2020-W12,11,222,33333333,44.4444444444444,55.5555555555555,fghij
France,FR,2020-W12,10595,73235,67012883,109.28495644636,14.4671263740015,TESSy
France,FR,2020-W13,24156,122870,67012883,183.35280396756,19.6598030438675,TESSy
Belgium,BE,2020-W13,1111,222222,33333333,444.44444444444,55.5555555555555,abcde
Belgium,BE,2020-W14,1111,222222,33333333,444.44444444444,55.5555555555555,abcde
France,FR,2020-W14,30304,127029,67012883,189.55907329043,23.8559698966378,TESSy
France,FR,2020-W15,24925,140316,67012883,209.386604065371,17.7634767239659,TESSy
EOD
set datafile separator comma
set datafile missing NaN
set xtics rotate by -45
myFilter(dcol,fcol,key) = strcol(fcol) eq key ? (t=t+1, column(dcol)) : NaN
myXtic(col) = sprintf("%s",(t+myOffset)% myEvery ? "" : strcol(col))
myKey = 'France'
myOffset = 0
myEvery = 2
plot t=1 $Data u (t):(myFilter(4,1,myKey)):xtic(myXtic(3)) w lp pt 7 title myKey
### end of code
Result:
The basic error is that the Y_W function is looking in the wrong columns for the week number. It should be substring 7 to 8 not 2 to 3.
Y_W(col) = timecolumn(col,"%Y") + SECPERWEEK * (strcol(col)[7:8])
As explained by theozh in this answer, gnuplot uses American week numbers by default, not ISO 8601, so I have not addressed that here.
I am trying to get the month of a date in gnuplot 5.4.
Consider the following data:
2019/01/01
2019/02/01
2019/03/01
2019/04/01
2019/05/01
2019/06/01
2019/07/01
2019/08/01
2019/09/01
2019/10/01
2019/11/01
2019/12/01
2020/01/01
2020/02/01
2020/03/01
2020/04/01
2020/05/01
2020/06/01
2020/07/01
2020/08/01
2020/09/01
2020/10/01
2020/11/01
2020/12/01
For each data point, I want to show the full date on the x axis and the month number (0-11) on the y axis.
The gnuplot documentation recommends using the tm_mon function for such a task, which should return the month number for a given date.
As far as I understand, the following gnuplot script should do what I want:
#!/bin/gnuplot
set timefmt '%Y/%m/%d'
set xdata time
set format x '%m/%y'
set datafile separator ','
plot "data.csv" using 1:(tm_mon($1)) title 'data'
But that is not the case. This gnuplot script correctly shows dates on the x axis but has a constant 0 on the y axis.
What am I doing wrong? Why is tm_mon($1) constantly returning 0?
I'm not sure whether I fully got your intention.
I understand you want column 1 as xtic labels.
However, there is a difference between just taking the column 1 as xtic labels or interpreting column 1 as date/time and scaling the x-axis accordingly and gnuplot would take care automatically about the xtic labels.
For the first case, the width of the graph might not be wide enough to show all labels without overlap, so, I reformatted date. Check help strptime and help strftime. By the way, help tm_mon says it needs input in seconds, not in your date format as it is in $1, there for use strptime().
I understand you want the yrange ranging from 1 to 12 for the months of a year.
But where is the data you want to plot?
Maybe the following examples is a starting point to better find out what you really want.
Code:
### plotting dates...
reset session
$Data <<EOD
2019/01/01
2019/02/01
2019/03/01
2019/04/01
2019/05/01
2019/06/01
2019/07/01
2019/08/01
2019/09/01
2019/10/01
2019/11/01
2019/12/01
2020/01/01
2020/02/01
2020/03/01
2020/04/01
2020/05/01
2020/06/01
2020/07/01
2020/08/01
2020/09/01
2020/10/01
2020/11/01
2020/12/01
EOD
myTimeInputFmt = "%Y/%m/%d"
myTimeOutputXFmt = "%Y\n%m\n%d"
set xlabel "Date"
set format x myTimeOutputXFmt # to get enough space for the 3 lines of the label
set ylabel "Month"
set yrange [0.5:12.5]
set ytics 1
plot $Data u 0:(tm_mon(strptime(myTimeInputFmt,strcol(1)))+1): \
xtic(strftime(myTimeOutputXFmt,strptime(myTimeInputFmt,strcol(1)))) \
with points pt 7 lc "red" title 'data'
### end of code
Result:
Another way to read data properly
There is also the function 'timecolumn(N, "timeformat")' in gnuplot, although it can only be used in using. This is the function for reading the Nth column of input data as a datetime. The second argument of this function is optional if you use the format given by set timefmt. With it, your script will work by the following script.
#!/bin/gnuplot
set timefmt '%Y/%m/%d'
set xdata time
set format x '%m/%y'
set datafile separator ','
plot "data.csv" using 1:(tm_mon(timecolumn(1))) title 'data'
Why is tm_mon($1) constantly returning 0?
In your script, tm_mon($1) is interpreted as tm_mon("2019/01/01") when reading first line from 'data.csv'. tm_mon basically accepts the real value that represents an UNIX time as the argument. But, if a string value is given, tm_mon try to convert it into the real value and interpret as an UNIX time. So, tm_mon doesn't constantly returning 0. You would understand this behavior by trying the following commands.
gnuplot> print tm_mon(1607698800) ### 2020-12-12 in UNIX time
11.0
gnuplot> print tm_mon("1607698800")
11.0
gnuplot> print tm_mon("1607698800/05/06")
11.0
$data << EOD
1563619139 10
1532083139 9
1500547139 8
1469011139 7
1437388739 6
1405852739 5
1374316739 4
1342780739 3
1311158339 2
1279622339 1
EOD
set terminal png
set xdata time
set timefmt "%s"
set format x '%Y'
unset key
plot '$data' u 1:2
How do I plot values only from say 2015? I tried plot ["2015":] '$data' u 1:2 via the docs but it doesn't work as expected.
I realise I could edit $data, but I don't want to do that.
There is an older an a newer gnuplot syntax for timedata.
The example below uses the newer syntax.
Check help time/date, help timecolumn, and help strptime.
Code:
### time data
reset session
$Data << EOD
1563619139 10
1532083139 9
1500547139 8
1469011139 7
1437388739 6
1405852739 5
1374316739 4
1342780739 3
1311158339 2
1279622339 1
EOD
unset key
set format x "%Y" time
StartTime = strptime("%Y","2015") # 2015-01-01 00:00:00 in seconds after 1970
set xrange[StartTime:]
set xtics StartTime, 3600*24*365 # start time and major tic distance one year in seconds
plot $Data u (timecolumn(1,"%s")):2 w lp pt 7
### end of code
Result:
You must use the same format of timefmt to specify the range.
plot ["1420092000":] '$data' u 1:2
The seconds in Gnuplot are measured starting from 1970.
I calculated the starting time considering 365.25 days in a year, hence 1420092000 s, but using strptime("%Y","2015"), as reported in the other answer, is without doubt more correct and precise.
You can add
set xtics 31557600
to have only major tics corresponding to the beginning of year. The value specified is the time increment between tics that must be given in seconds.
I am (somehow) familiar with the smooth/interpolation techniques in Gnuplot. It seems to me that these interpolations work only for plotting the interpolated values. However, I need the interpolated values for further calculations.
A simple example may illustrate this:
Let’s say we are selling a specific item on four days and have the number of sales stored in input_numbers.dat:
# days | number_of_sold_items
1 4
2 70
3 80
4 1
Now, I want to plot my income for each day. But the relation between the price per item and the number of sold items is not a simple linear relation, but something complicate which is only known for a few examples – stored in input_price.dat:
# number_of_sold_items | price_per_item
1 5.00
3 4.10
10 3.80
100 3.00
How can I do something like this (pseudocode):
make INTERPOLATED_PRICE(x) using "input_price.dat"
plot "input_numbers.dat" using 1:($2*INTERPOLATED_PRICE($2))
I can do it by fitting but it is not what I want. The relation of the data is too complicated.
P.S.: I know that the price per item vs the number of items in such an example is more like a step-like function and not smooth. This is just an example for some interpolation in general.
It’s hard to prove the non-existence of something but I am pretty confident that this cannot be done with Gnuplot alone, as:
I am under the illusion to be sufficiently familiar with Gnuplot that I would know about it if it existed.
I cannot find anything about such a feature.
It would completely go against Gnuplot’s paradigm to be a one-purpose tool for plotting (fitting is already borderline) and not to feature data processing.
Gnuplot can do something like this:
text = "%f*x + %f"
a = 2
b = 10
eval("f(x) = ".sprintf(text,a,b))
set grid x y
plot f(x)
which basically means that complicated functions can be defined dynamically: The sprintf command converts the text "%f*x + %f" into "2.0*x + 10", the dot operator . concatenates the strings "f(x) = " and "2.0*x + 10", and the eval command defines the function f(x) = 2.0*x + 10. The result can be plotted and gives the expected diagram:
This behavior can be used for creating a piecewise interpolation function as follows:
ip_file = "input_price.dat"
stats ip_file nooutput
n = STATS_records - 1
xmin = STATS_min_x
xmax = STATS_max_x
ip_f = sprintf("x < %f ? NaN : ", xmin)
f(x) = a*x + b # Make a linear interpolation from point to point.
do for [i=0:n-1] {
set xrange [xmin:xmax]
stats ip_file every ::i::(i+1) nooutput
xmintemp = STATS_min_x
xmaxtemp = STATS_max_x
set xrange [xmintemp:xmaxtemp]
a = 1
b = 1
fit f(x) ip_file every ::i::(i+1) via a, b
ip_f = ip_f.sprintf("x < %f ? %f * x + %f : ", xmaxtemp, a, b)
}
ip_f = ip_f."NaN"
print ip_f # The analytical form of the interpolation function.
eval("ip(x) = ".ip_f)
set samples 1000
#set xrange [xmin:xmax]
#plot ip(x) # Plot the interpolation function.
unset xrange
plot "input_numbers.dat" using 1:($2*ip($2)) w lp
The every in combination with stats and fit limits the range to two successive datapoints, see help stats and help every. The ternary operator ?: defines the interpolation function section by section, see help ternary.
This is the resulting analytical form of the interpolation function (after some formatting):
x < 1.000000 ? NaN
: x < 3.000000 ? -0.450000 * x + 5.450000
: x < 10.000000 ? -0.042857 * x + 4.228571
: x < 100.000000 ? -0.008889 * x + 3.888889
: NaN
This is the resulting interpolation function (plotted by plot ip(x)):
This is the resulting plot using the interpolation function in another calculation (plot "input_numbers.dat" using 1:($2*ip($2))):
I don't know the limits on how many ternary operators you can nest and on how long a string or a function definition can be, ...
Tested with Gnuplot 5.0 on Debian Jessie.
Linear interpolation is not available, but how about this:
set xr [0:10]
set sample 21
# define an inline example dataset
$dat << EOD
0 1
2 2
4 4
6 5
8 4
10 3
EOD
# plot interpolated data to another inline dataset
set table $interp
plot $dat us 1:2 with table smooth cspline
unset table
plot $dat w lp, $interp w lp
As I understand your question, you are not looking for interpolation but for a lookup-table, i.e. depending on the number of sold items you have a different price.
What you can do with gnuplot is:
(mis)using stats to create a lookup-string (check help stats)
(mis)using sum to create a lookup-function (check help sum)
Comment: I assume it will be a difference if you for example sell 3 times 1 item on a single day or 1 time 3 items on a single day, because of the graduation of prices.
So, I would suggest a different input data format, i.e. with a date.
(However, not yet implemented in the example below, but can be done. Then, you can make use of the smooth frequency option.) Some data format, e.g. like this:
# date sold_items
2022-09-01 1
2022-09-01 1
2022-09-01 1
2022-09-02 3
Script: (works with gnuplot 5.0.0, Jan. 2015)
### implement lookup table
reset session
$SALES <<EOD
# days | number_of_sold_items
1 4
2 70
3 80
4 1
EOD
$PRICE <<EOD
# number_of_sold_items | price_per_item
1 5.00
3 4.10
10 3.80
100 3.00
EOD
LookupStr = ''
stats $PRICE u (LookupStr=LookupStr.sprintf(" %g %g",$1,$2)) nooutput
Lookup(v) = (p0=NaN, sum [i=1:words(LookupStr)/2] (v>=real(word(LookupStr,i*2-1)) ? \
p0=real(word(LookupStr,i*2)) : 0), p0)
set grid x,y
set key noautotitle
set multiplot
plot $SALES u 1:2 w lp pt 6 lc "dark-grey" ti "sold items", \
'' u 1:($2*Lookup($2)) w lp pt 7 lc "red" ti "total income"
# price table as graph inset
set origin x0=0.41, y0=0.42
set size sx=0.30, sy=0.28
set obj 1 rect from screen x0,y0 to screen x0+sx,y0+sy fs solid noborder lc "white" behind
set margins 0,0,0,0
set xrange [:150]
set yrange [2.5:5.5]
set xlabel "pieces" offset 0,0.5
set ylabel "price / piece"
set logscale x
plot $PRICE u 1:2 w steps lc "blue", \
'' u 1:2 w p pt 7 lc "blue"
unset multiplot
### end of script
Result: