7

I'd like to plot with PSTricks some data from Matlab.

I usually plot these data using the imagesc and the colorbar in Matlab, but I'd rather do it in LaTeX...

Here is the picture I want to plot in LaTeX : enter image description here

It's actually plotting 2 vectors (time and velocity) and 1 array (the color), but I can't figure how to do it...

Is there a special PSTricks package to do it ? If it could read the 3 data files, I'd be simple... If it's just a couple of commands, it's good too...

Edit : providing data files

Here are the data (all are .csv files):

  • time is an 175x1 matrix

  • velocity is an 14112x1 matrix

  • tension is ans 14112x175 matrix...

I compressed them in a zip file

The data are quite huge, but an example with 10 points is good too..

dustin
  • 18,617
  • 23
  • 99
  • 204
3isenHeim
  • 2,107
  • Provide a data set. –  May 22 '14 at 07:44
  • Done. I edited the post. – 3isenHeim May 22 '14 at 09:22
  • ok, but I do not understand how to build the data records (x,y,z) when you have different numbers of data in each file. –  May 22 '14 at 12:23
  • I think we have to draw something like a meshgrid (with timeand velocity), and associate to each rectangle a color, in function of the tension...

    I can provide you a meshgrid file (the matrix product between time and velocity), if you'd like to...

    But don't spend ages on that, we're not about to create a new pst-package for it ;)

    – 3isenHeim May 22 '14 at 17:46
  • Have you tried something already? Please provide the data in a "usable" form as people here don't know necessarily how the plot was generated. – Trefex May 26 '14 at 13:40
  • Have you tried matlab2tikz? – Trefex May 26 '14 at 18:41
  • @Pierre Are you sure that data set is related to that presented graph? Or is that graph included just for illustration purposes? I'm just asking as time starts from 1 and ends with 3.5, speed starts with 0 and ends with 4772.3, most of the data in tension is -100 which is the lowest value (dark blue). I haven't tried to draw it, but we might face some drawing limitations if we would be to draw 14112x175 independent rectangles (my first idea went to TikZ). – Malipivo May 26 '14 at 22:57
  • @Trefex when you use matlab2tikz with a plot which was generated with matlabs imagesc command it will create a .png file of the data and include that. The axis and labels will however be in LaTeX. – WG- May 27 '14 at 10:55
  • @WG well depending on what OP wants, this could be enough, eg having LaTeX font for the labels or so – Trefex May 27 '14 at 20:02
  • A workflow using R and pgfplots is described at generate a surf plot from a text file – Jake May 28 '14 at 08:07
  • Hm, aren't time and velocity just (nearly) linear vectors, such that the axis are normal axis and the thing to be drawn is an image having values from the tension.csv (and then labe the axis correctly? I think the best way to store the tension would be an imwrite (using the jet colormap from matlab as you use) and save it as an PNG instead of drawing it in TeX/TikZ/,,, because it is not a vector graphic per se. – Ronny May 28 '14 at 22:03

2 Answers2

7

It uses the data file from Malipivo and the pstricks-add.tex from http://texnik.dante.de/tex/generic/pstricks-add/. Run it with

latex --shell-escape <file>
dvips <file>
ps2pdf -dNOSAFER <file>.ps

shell-escape is needed to run from within the document the external texlua which creates on the fly the data file with PSTricks structure. The data files must be ibn the same directory as this document:

\documentclass{article}
\usepackage{pstricks-add}
\usepackage{filecontents}
\begin{filecontents*}{data.lua}
local c=0 -- a counter of data
print("Cashing 3 files...")
time="time.csv" -- 175
speed="speed.csv"
tension="tension.csv"
local times={}
for time in io.lines(time) do table.insert(times,time) end 
local speeds={}
for speed in io.lines(speed) do table.insert(speeds,speed) end 
local tensions={} 
for tension in io.lines(tension) do table.insert(tensions,tension) end 
topst=io.open("image.data","w")
topst:write("/contourdata [")
print("Processing "..#tensions.." lines...")
for tension=1,200 do -- #tensions or 300
  c=0
  topst:write("[\n")
  for mdata in string.gmatch(tensions[tension],"[^,]+") do
    c=c+1
    writeme=speeds[tension].." "..times[c].." "..mdata.."\n"
    topst:write(writeme)
  end 
topst:write("]")
end -- for tension

topst:write("] def\n")
\end{filecontents*}

\begin{document}
\immediate\write18{texlua data.lua}
\psset{xunit=1mm,yunit=2.5}
\begin{pspicture}(0,1)(70,3.5)
\pstContour[colored,colorOffset=100 add]{image.data}
\psaxes[labelFontSize=\footnotesize,mathLabel=false,Dx=10,Dy=0.5,Oy=1,
        ticksize=-5pt 0](0,1)(70,3.5)
\multido{\rA=1.0+0.01,\iA=383+1}{250}{\psline[linecolor={[wave]\iA}](70,\rA)(75,\rA)}
\psaxes[xAxis=false,Oy=-100,Dy=3,dy=0.5,ticksize=0 4pt,ylabelPos=right](75,1)(75,3.5)
\end{pspicture}
\end{document}

enter image description here

5

Partial solution

I've downloaded and unzipped your ZIP file. In that folder I created a standalone Lua script (mal-preprocess.lua) which processes those three data sets.

The output is one file suitable for PSTricks (toimage-pst.data) and one file (toimage.data) for PGFplots. I don't know how to set the graph properly in PSTricks and I'm reaching limits in PGFplots/pdflatex, therefore an enclosed example is limited from #tensions (number of lines; line 33 in the Lua code) to the first 200 entries.

I run in that folder:

texlua mal-preprocess.lua

These are skeletons of the TeX files, we run:

latex mal-contour.tex
dvips mal-contour.dvi
ps2pdf mal-contour.ps

and

lualatex mal-contour-pgfplots.tex

I enclose the Lua code, those two TeX files and a preview of the snippet from PGFplots (I'm having some difficulties with ps2pdf). The mal-preprocess.lua file is:

-- I am mal-preprocess.lua...
-- I take 3 data sets and prepare data set for PSTricks...

--local pstricks=0 -- 0 (pgfplots) or 1 (pstricks)
local c=0 -- a counter of data

-- Cashing files...
print("Cashing 3 files...")
time="time.csv" -- 175
speed="speed.csv"
tension="tension.csv"
local times={}
for time in io.lines(time) do
table.insert(times,time)
end -- for time
local speeds={}
for speed in io.lines(speed) do
table.insert(speeds,speed)
end -- for speed
local tensions={}
for tension in io.lines(tension) do
table.insert(tensions,tension)
end -- for tension

-- The core...
whereto=io.open("../toimage.data","w")
topst=io.open("../toimage-pst.data","w")
topst:write("/contourdata [")

print("Processing "..#tensions.." lines...")
-- Load all lines...
--local temp=""
for tension=1,200 do -- #tensions or 300
c=0
topst:write("[\n")
-- Parse that one line...
for mdata in string.gmatch(tensions[tension],"[^,]+") do
  c=c+1
  writeme=speeds[tension].." "..times[c].." "..mdata.."\n"
  whereto:write(writeme)
  topst:write(writeme)
end -- for mdata

topst:write("]")
whereto:write("\n")
end -- for tension

topst:write("] def\n")

This is the mal-contour.tex file:

% run: latex mal-contour.tex
% -> ps; ->pdf
\documentclass{article}
\usepackage{pstricks-add}
\begin{document}
\psset{unit=0.1cm}
\begin{pspicture}[showgrid](0,1)(4775,3.5)
\pstContour[colored]{toimage-pst.data}
\end{pspicture}
\end{document}

The second file is the mal-contour-pgfplots.tex file:

% run: lualatex engine mal-contour-pgfplots.tex
\documentclass[a4paper]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.10}
\begin{document}
\begin{tikzpicture}
\begin{axis}[view={0}{90},colorbar,grid=none]
\addplot3[surf,shader=interp,mesh/cols=175] file {toimage.data};
\end{axis}
\end{tikzpicture}
\end{document}

mwe

I believe that GNUplot is a better tool for manipulating huge data sets. I would recommend to use PNG file at the TeX level instead of a vector form as there are so many elements in it. This is a fast test (mal-test.plt) for GNUplot, I enclose the code and a preview of mal-test.png which can be loaded by the \includegraphics command from the graphicx package.

set terminal png
set output "mal-test.png"
unset key

set title ""
set xlabel ""
set ylabel ""

set xrange [ 0.0000 : 84.30000 ] noreverse nowriteback
set yrange [ 1.0000 : 3.50000 ] noreverse nowriteback
set zrange [ -100.0000 : -85.00000 ] noreverse nowriteback

splot "toimage.data"

mwe, GNUplot

Update: A note on the data transformation

You can picture your three files as here (one file consists the first row, the second file consists the first column and the last file consists the cells/data set):

- A B C D
X 1 2 3 4
Y 5 6 7 8
Z 9 0 1 2

We transform them to this form by repeating the labels from the first row and from the first column (however, the file size of data changed significantly from 96200+12390248+1199=12487647 to 48643360 bytes - toimage.data - that's the reason we usually don't save data in this form):

X A 1
X B 2
X C 3
X D 4

Y A 5
Y B 6
Y C 7
Y D 8

Z A 9
Z B 0
Z C 1
Z D 2
Malipivo
  • 13,287
  • I did'nt fully understand your Lua code, but I wonder how you build your .data file... I'm working with Matlab, and I could export some data directly as a .data, but I have to know how your file is build...

    Have you create a matrix with time and velocity ? And how do you superimpose it the tention points ?

    But thanks anyway for your involvment ! :)

    – 3isenHeim May 28 '14 at 22:34