bstpierre
bstpierre

Reputation: 31206

generate fence plot from series of (x, y, z) data points

I have some car price data in the form (year, mileage, price) as (x, y, z):

2018 53313 17590
2017 106000 10000
2017 69294 16495
2015 88000 13995
2017 38968 17732
...

I use a python script to sort by year and mileage, and discarding any years with only a single data point, to end up with a dat file as shown below. I ended up with this format based on the answer here.

2014 45281 16995                               
2014 45281 0     
                       
2014 89199 15990                               
2014 89199 0     
                       
2014 115585 10500                              
2014 115585 0    
                       

2015 44477 17962       
2015 44477 0    
                       
2015 77486 14500                               
2015 77486 0    
                       
2015 88000 13995                               
2015 88000 0    
                       

2016 58751 15998                               
2016 58751 0    
                       
2016 75857 14797                               
2016 75857 0    
...

My gnuplot script is:

set terminal png size 800,500 enhanced font "Segoe UI,10"
set output "3d.png"

set zrange [9000:20000]
set hidden3d offset 0

# This is close, but doesn't show "fences"
splot for [i=0:15] "3d.dat" index i u 1:2:3 w lines notitle

and I get this output: 3d plot

This is close, but I'm hoping to achieve something more like the plot shown on this page:

I'm not how to achieve the solid effect. The data series used for that chart appears to be a set of z values where the y values are evenly spaced -- but my y values are irregular. I can change the python script to reformat the data as needed, I just don't know what shape it needs to have to achieve the kind of plot I'm looking for.

Upvotes: 0

Views: 70

Answers (1)

theozh
theozh

Reputation: 25748

My preference would be if you can leave the original data as is and you do the necessary processing (if possible) in gnuplot. Check the example below.

Some comments:

  • in the example below, some random test data is generated
  • find first and last year via stats (check help stats)
  • a for loop is used to go through the data by year
  • smooth uniq is used to sort the entries by mileage. If there might be more than one price for the same mileage in a year, smooth uniq will return the average price (check help smooth).
  • data is written to a table/datablock $Sort and due to the for loop, the years are in subblocks separated by two empty lines
  • subblocks can be addressed via index (check help index)
  • fences can be plotted with plotting style with zerrorfill

I noticed again that the ticlabels apparently can't be rotated in splot How to rotate tic labels in 3D in gnuplot?

Script: (works with gnuplot>=5.2.0, Sept. 2017)

### plot z-fence, here: x: year, y: mileage, z: price
reset session

# create some random test data
set table $Data
    plot '+' u (2014+int(rand(0)*7)):(int(rand(0)*9e4+1e4)):(int(rand(0)*4e4+1e4)) w table
unset table

stats $Data u 1 nooutput  # find start and end year
y0 = STATS_min
y1 = STATS_max

set key noautotitle
set grid x,y,z
set xyplane relative 0
set border 1+2+4+8+16+32+64+256+512
set style fill solid 0.4
set xlabel "year" rotate parallel offset 0,-0.5 font ",12"
set xtics out offset 0,-0.5
set ylabel "mileage" rotate parallel font ",12"
set ytics out 20000 
set zlabel "price" rotate by 90 offset -3,0 font ",12"
set ztics out 10000
set datafile missing NaN

set table $Sort
    plot for [y=y0:y1] $Data u ($1==y?$2:NaN):3 smooth uniq
unset table

splot for [y=y0:y1] $Sort index y-y0 u (y):1:2:0:2 w zerrorfill 
### end of script

Result:

enter image description here

Upvotes: 1

Related Questions