Создание глазковой диаграммы с помощью gnuplot

Я хотел бы построить более 1000 кривых и отобразить их глазковую диаграмму с помощью gnuplot.

Пример примера глазковой диаграммы с Matlab: http://www.mathworks.fr/fr/help/comm/ref/commscope.eyediagram.html

Я уже могу построить кривые, используя скрипт ниже:

gnuplot> plot for [col=1:1000] 'input_dataset1.txt' using 0:col with lines linecolor rgb("#0000ff")

Результат: output_image.png Проблема в том, что при пересечении двух линий цвет точки пересечения совпадает с линия. На глазковой диаграмме область с большим количеством пересечений должна отображаться другим цветом.

Я не нашел ни одного примера таких диаграмм, сделанных с помощью gnuplot.

Игра с прозрачностью линии не сработала: пересечение двух полупрозрачных линий имеет тот же цвет, что и линия.

Есть идеи ?

Спасибо,


person ordepedro    schedule 30.04.2014    source источник
comment
Вам нужен 2D-график ваших данных? Если это так, загляните в команду splot или «постройте матрицу data.txt с изображением». Я спрашиваю, потому что глазковая диаграмма выглядит так же, как специальное использование для 2D-графика.   -  person andyras    schedule 30.04.2014
comment
Для этого вы должны создать гистограмму с помощью внешнего инструмента, см., например. создать heatmap2d из txt-файла.   -  person Christoph    schedule 30.04.2014


Ответы (1)


Я разработал способ сделать это только с помощью gnuplot, он требует немного работы, и вам, вероятно, придется точно настроить детали для вашей конкретной проблемы.

В качестве примера я создал файл данных, содержащий значения для функции exp(x) и ее расширений Тейлора от нулевого порядка (T^(0)[exp(x)] = 1) до порядка 3 (T^(3)[exp(x)] = 1 + x + x**2/2. + x**3/6.). Этот тип данных подходит для этой проблемы, потому что у вас будет высокая плотность данных вокруг начала координат, где все приближения сходятся к точному значению, и более низкая плотность данных вдали от него. Его можно сгенерировать с помощью gnuplot следующим образом:

set xrange [0:1]
set table
set output "| grep -v '^$' > data"
plot exp(x), 1, 1+x, 1+x+x**2/2., 1+x+x**2/2.+x**3/6.
unset table ; unset output

Примечание. Я форматирую вывод, чтобы в моем файле данных не было пустых строк, иначе gnuplot обрабатывает поля, разделенные пустыми строками, как разные блоки данных, и это в конечном итоге искажает гистограммы ниже. Эти данные выглядят так (plot "data"):

введите здесь описание изображения

Теперь я создаю двумерную гистограмму с этими данными. Было бы очень полезно, если бы gnuplot предлагал эту функцию, но это не так, поэтому задача немного усложняется. Что я сделаю, так это создам несколько одномерных гистограмм. Для получения дополнительной информации о том, как сгенерировать последний, проверьте это.

Прежде всего, нужно определить ширину вдоль x и y для ваших бинов, xwidth и ywidth, где подсчитывается количество точек данных, то есть мы делим пространство данных на сетку, где каждый элемент измеряется xwidth на ywidth и присвоено число, равное количеству точек данных, содержащихся внутри. Чем меньше эти элементы, тем лучшее разрешение будет у вашего графика, но также тем больше точек данных вам потребуется, чтобы он выглядел хорошо. Для моих данных выше это может быть что-то вроде

xwidth = 0.02
ywidth = 0.05

Теперь мы объявляем функцию для определения наших одномерных бинов (детали):

bin(x,width)=width*floor(x/width)+width/2.0

и определите количество бинов вдоль каждого направления. Поскольку xrange для моих данных равно [0:1], а yrange равно [1:2,8], количество бинов будет 50 и 36 соответственно. Я мог бы использовать Nx = xrange / xwidth, но это привело бы к числу с плавающей запятой Nx, а мне нужно целое число. Чтобы быть в безопасности, я делаю:

Nx = 50
Ny = 36

Возможно, имеет смысл определить эти значения наоборот: вычислить xwidth как xrange / Nx, и в этом случае у вас не должно возникнуть проблем с целочисленным/плавающим числом.

Теперь я генерирую одномерные гистограммы вдоль y, перебирая x значений:

set output "| grep -v 'u\\|^$' | sed 's/#/\\n#/g' > data2"
set table
plot for [i=0:(Nx-1)] "./data" using \
(bin($2,ywidth)):( i*xwidth <= $1 && (i+1.)*xwidth > $1 ? 1.0 : 0.0) \
smooth freq
unset table ; unset output

Теперь data2 содержит Nx блоков данных, каждый из которых представляет собой сканирование вдоль y с Ny точками данных. Значение этих точек данных равно количеству записей данных в исходном файле data. Как бы то ни было, data2 содержит 2D-данные (y, color), которые мне нужно преобразовать в 3D. Значение x задается позицией блока данных, доступной с помощью опции every в gnuplot. Чтобы построить это трехмерное изображение, я делаю:

set output "| grep -v 'u\\|^$' | sed 's/#/\\n#/g' > data3"
set table
splot for [i=0:(Nx-1)] "./data2" every :::i::i using \
((i+0.5)*xwidth):1:2
unset table ; unset output

Теперь это data3 можно представить в виде цветовой карты:

plot "./data3" with image

который выглядит так:

введите здесь описание изображения

Если бы я использовал данные более высокого качества (то есть с более высоким разрешением), график выглядел бы лучше. С 2-кратным разрешением по каждому направлению то же самое выглядит следующим образом:

введите здесь описание изображения

person Miguel    schedule 05.05.2014