2016-02-16 5 views
2

Я ищу способ построить гистограммы в 3d, чтобы создать что-то вроде этой цифры http://www.gnuplot.info/demo/surface1.17.png, но где каждая серия представляет собой гистограмму.Гистограмма Gnuplot 3d

Я использую процедуру, приведенную здесь https://stackoverflow.com/a/19596160 и http://www.gnuplotting.org/calculating-histograms/ для создания гистограмм, и она отлично работает в 2d. В основном, команды, которые я использую

hist = 'u (binwidth*(floor(($2-binstart)/binwidth)+0.5)+binstart):(1) smooth freq w boxes 
plot 'data.txt' @hist 

Теперь я просто хотел бы добавить несколько гистограмм в том же участке, но потому, что они перекрывают друг друга в 2D, я хотел бы пространство их в 3D-сюжет.

Я попытался сделать следующую команду (с помощью описанной выше процедуры)

hist = 'u (1):(binwidth*(floor(($2-binstart)/binwidth)+0.5)+binstart):(1) smooth freq w boxes 
splot 'data.txt' @hist 

Но Gnuplot жалуется, что значения Z не определены.

Я не понимаю, почему это не поместило бы гистограмму вдоль значения 1 по оси x с бункерами вдоль оси y и построила высоту по оси z.

Мои данные отформатированы просто в двух столбцах:

Index angle 
0  92.046  
1  91.331  
2  86.604  
3  88.446  
4  85.384  
5  85.975  
6  88.566  
7  90.575  

У меня есть 10 файлов, как это, и так как значения в файлах близки друг к другу, они будут полностью перекрываться, если я сюжет их всех одна 2-гистограмма. Поэтому я хотел бы видеть 10 гистограмм друг за другом в некой 3D-перспективе.

+0

Просьба представить некоторые выборочные данные из вашего файл данных. – Matthew

+0

Вы также можете посмотреть эту статью: [http://www.phyast.pitt.edu/~zov1/gnuplot/html/bargraphs.html](http://www.phyast.pitt.edu/~zov1 /gnuplot/html/bargraphs.html) – Matthew

+0

Я добавил формат данных, которые я использую. И спасибо за ссылку, но я до сих пор не могу понять, как я могу использовать ее для моей ситуации (возможно, из-за непонимания). –

ответ

0

Это второй ответ отличается от моего первого. Принимая во внимание, что первый вопрос, который пытается выполнить ОП, второй вариант представляет собой альтернативный подход, который решает основную проблему, которую ОП пытается преодолеть.

Я отправил ответ, в котором рассматривается возможность сделать это в 3d. Однако, как правило, это не лучший способ сделать это с помощью нескольких гистограмм, подобных этому. Подобный трехмерный график будет трудно сравнить.

Мы можем адресовать перекрытие в 2D, затормозив положение ящиков. С настройками по умолчанию, коробки будут распространяться на сенсорный. Мы можем отключить это и отрегулировать положение ящиков, чтобы на графике было больше 1 гистограммы. Помните, что координаты, которые вы поставляете, являются центрами ящиков.

Предположим, что у меня есть данные, которые вы предоставили, и это дополнительные набор данных

Index Angle 
0 85.0804 
1 92.2482 
2 90.0384 
3 99.2974 
4 87.729 
5 94.6049 
6 86.703 
7 97.9413 

Мы можем установить ширину рамки до 2 единиц с set boxwidth 2 (ваши бункеры 4 единицы в ширину). Кроме того, мы включим коробку с set style fill solid border lc black.

Тогда я могу выпустить

plot datafile1 u (binwidth*(floor(($2-binstart)/binwidth)+0.5)+binstart):(1) smooth freq w boxes, \ 
    datafile2 u (binwidth*(floor(($2-binstart)/binwidth)+0.5)+binstart+1):(1) smooth freq w boxes 

Вторая команда участка идентична первой, за +1 после binstart исключением. Это сдвинет этот блок на 1 блок вправо. Это приводит к

enter image description here

Здесь две серии ясно. Следить за тем, какая коробка связана с каждой из них, легко из-за перекрытия, но этого недостаточно, чтобы замаскировать другие серии.

Мы можем даже перемещать их рядом друг с другом, без перекрытия, путем вычитания 1 из первой команды участка:

plot datafile1 u (binwidth*(floor(($2-binstart)/binwidth)+0.5)+binstart-1):(1) smooth freq w boxes, \ 
    datafile2 u (binwidth*(floor(($2-binstart)/binwidth)+0.5)+binstart+1):(1) smooth freq w boxes 

производства

enter image description here

+0

Спасибо за два примера, и я согласен, когда смотрю на оба ответа, что это, вероятно, то, что я хочу. Сначала меня отбросило то, что моя ось х непрерывна (не похожа на «Америку», «Канаду», «Мексику», где было бы явно иметь смысл отделить их). –

0

Этот первый ответ отличается от моего второго. Этот ответ касается того, что пытается выполнить ОП, тогда как вторая касается основной проблемы, которую ОП пытается преодолеть.

Gnuplot не собирается быть в состоянии сделать это на своем собственном, так как соответствующие стили (коробки и гистограмм) работают только в 2D. Вам нужно будет сделать это, используя внешнюю программу.

Например, используя ваши данные и ваш 2d команды (ваша первая команда), мы получаем (используя ваши данные и связанные значения -100 и 4 для binstart и binwidth)

enter image description here

Для нарисуйте эти квадратики на 3d-сетке, нам нужно будет использовать стиль линии и иметь по четыре точки для каждого: нижний левый, верхний левый, верхний правый и нижний правый. Мы можем использовать предыдущую команду и захватить ее в таблицу, но это даст только верхнюю центральную точку. Однако мы можем использовать внешнюю программу для предварительной обработки. Следующая программа python, makehist.py, делает именно это.

from sys import argv 
import re 
from math import floor 

pat = re.compile("\s+") 

fname = argv[1] 
binstart = float(argv[2]) 
binwidth = float(argv[3]) 

data = [tuple(map(float,pat.split(x.strip()))) for x in open(fname,"r").readlines()[1:]] 

counts = {} 
for x in data: 
    bn = binwidth*(floor((x[-1]-binstart)/binwidth)+0.5)+binstart 
    if not bn in counts: counts[bn] = 0 
    counts[bn]+=1 

for x in sorted(counts.keys()): 
    count = counts[x] 
    print(x-binwidth/2,0) 
    print(x-binwidth/2,count) 
    print(x+binwidth/2,count) 
    print(x+binwidth/2,0) 

print(max(counts.keys())+binwidth/2,0) 
print(min(counts.keys())-binwidth/2,0) 

По сути, данная программа делает то же самое, как вариант smooth frequency делает, но вместо того, чтобы верхний центр каждой коробки, мы получаем четыре ранее упомянутые пункты наряду с двумя точками, чтобы нарисовать линию вдоль дна всех ящиков.

Запуск следующую команду,

plot "< makehist.py data.txt -100 4" u 1:2 with lines 

производит

enter image description here

, который выглядит очень похож на оригинальный график. Мы можем использовать это в 3D сюжет

splot "< makehist.py data.txt -100 4" u (1):1:2 with lines 

, который производит

enter image description here

Это не все, что красиво, но закладывают гистограмму на 3D-сюжет. Тот же метод может использоваться для добавления на него нескольких файлов данных. Например, с дополнительными данными

Index Angle 
0 85.0804 
1 92.2482 
2 90.0384 
3 99.2974 
4 87.729 
5 94.6049 
6 86.703 
7 97.9413 

Мы можем использовать

splot "< makehist.py data.txt -100 4" u (1):1:2 with lines, \ 
     "< makehist.py data2.txt -100 4" u (2):1:2 with lines 

производить

enter image description here

Смежные вопросы