У меня есть файлы данных со следующей структурой. Первые три столбца — это трехмерные координаты (x, y, z) точек, а четвертый столбец — значение интенсивности. Ряды значений в каждой группе (т. е. количество баллов в каждой группе) могут различаться. Поэтому мне нужна функция, которая автоматически подсчитывает количество точек при построении графика, чтобы я мог получить заголовок легенды, например «group_0001: 10 точек». Я также хочу, чтобы интенсивность точек отображалась с прозрачностью, а не с размером.
reset session
$Data <<EOD
# group_0001
125.714 109.647 38.0402 0.79257
128.834 111.153 40.7486 0.753538
132.036 112.698 43.4124 0.793434
135.52 114.449 46.0812 0.776121
138.786 116.233 48.1499 0.793355
142.357 117.967 50.2387 0.731456
145.967 119.98 52.2324 0.787673
148.363 121.234 53.44 0.749578
149.448 121.81 54.0276 0.80474
153.108 123.831 55.9821 0.786737
# group_0002
111.44 146.587 81.1063 0.755904
112.27 151.103 82.1631 0.649881
112.995 155.321 83.3001 0.791218
113.763 159.66 84.2395 0.746114
114.551 163.53 85.1278 0.744113
115.437 168.114 86.1995 0.767338
116.344 172.465 87.481 0.742969
EOD
splot for [i=0:*] $Data index i pt 7 ps var
@theozh: как раз наоборот (1 = непрозрачный).
Используя этот трюк, вы можете подсчитать количество построенных точек данных и сбросить их для разных групп.
cur_i=0
n=0
init(i)=(cur_i=i,n=1)
count(i,col)=((i!=cur_i)?init(i):n=n+1,column(col))
splot for [i=0:*] $Data u 1:2:3:(count(i,4)) index i pt 7 ps var tit "group ".n." points"
Вот предложение, которое
Чтобы извлечь заголовки блоков, вы делаете set datafile commentschar ''
вместе с columnheader(2)
. Если ваши фактические данные выглядят иначе, их необходимо адаптировать.
Прозрачность рассчитывается в определенном диапазоне (здесь: от 0,6 до 0,9) и добавляется с помощью битового сдвига (<<24
) к цвету из списка.
Мне не удалось втиснуть все (например, переменный цвет и заголовок) в одну команду построения графика. Следовательно, существует вторая команда графика, которая на самом деле ничего не отображает (NaN
), а просто предоставляет желаемый заголовок. Возможно, есть более короткий путь, которого я пока не нашел.
Это работает только с gnuplot>=5.4.0, поскольку с тех пор оценка переменных в заголовке была изменена.
Скрипт: (работает для gnuplot>=5.4.0)
### variable transparency and legend with count of datalines in each block
reset session
$Data <<EOD
# group_0001
125.714 109.647 38.0402 0.79257
128.834 111.153 40.7486 0.753538
132.036 112.698 43.4124 0.793434
135.52 114.449 46.0812 0.776121
138.786 116.233 48.1499 0.793355
142.357 117.967 50.2387 0.731456
145.967 119.98 52.2324 0.787673
148.363 121.234 53.44 0.749578
149.448 121.81 54.0276 0.80474
153.108 123.831 55.9821 0.786737
# group_0002
111.44 146.587 81.1063 0.755904
112.27 151.103 82.1631 0.649881
112.995 155.321 83.3001 0.791218
113.763 159.66 84.2395 0.746114
114.551 163.53 85.1278 0.744113
115.437 168.114 86.1995 0.767338
116.344 172.465 87.481 0.742969
EOD
stats $Data u (B=column(-2)+1) nooutput # get number of blocks
set datafile commentschar ''
set key noautotitle noenhanced
set ztics 10
set grid x,y,z vertical
set xyplane relative 0
myColors = "0xff0000 0x00cc00 0x0000ff" # your color list
cMin = 0.60
cMax = 0.90
myColor(col,i) = ((int(0xff*(1-(column(col)-cMin)/(cMax-cMin))))<<24) + int(word(myColors,i+1))
splot for [b=0:B-1] $Data index b u 1:2:3:(myColor(4,b)) w p pt 7 ps 2 lc rgb var, \
for [b=0:B-1] '' index b u 1:2:(c=$0,NaN) w p pt 7 ps 2 \
lc rgb int(word(myColors,b+1)) ti sprintf("%s: % 3g pts.",columnheader(2), c)
### end of script
Результат:
Я добавляю гипертекстовые метки к точкам с помощью второго вызова графика и отображаю значения точек при наведении указателя мыши на точки. По мне так оптимизация не нужна. Это очень точное решение моей проблемы.
@magfan рад это слышать :-)
Могу ли я распечатать отсортированные кластеры? Сначала мне нужен самый большой кластер. Порядок кластеров одинакового размера не имеет значения.
@magfan под словом «напечатано» вы имеете в виду порядок в легенде по группе с наибольшим количеством точек данных в первую очередь? Сколько групп у вас обычно бывает?
Да, порядок в легенде. Обычно существует от трех до 20 групп.
@magfan ну, к сожалению, в gnuplot нет хороших внутренних функций для сортировки списков, блоков данных или массивов. Либо вам нужны внешние инструменты, либо немного громоздкие обходные пути. Здесь, на SO, есть несколько вопросов и ответов. Я подумаю, как действовать в вашем случае.
@magfan, если у вас есть определенная цветовая схема (например, красный, зеленый, синий, ...), хотите ли вы, чтобы цвета были фиксированы для кластера (т. е. группа1 = красный, группа2 = зеленый, ...) или для позиция (позиция1=красная, позиция2=зеленая, ...)?
Есть три возможности. Первый: группы сортируются по размеру и им присваиваются цвета в соответствии с порядком в таблице цветов. Второе: сделайте сопоставление размера и цвета, чтобы группы одинакового размера имели один и тот же цвет. В обоих случаях должно быть 18 разных цветов, чтобы четко различать все группы, где размеры групп 1 и 2 не существуют. Третье: один цвет для всех групп, но интенсивность должна масштабироваться между минимальным и максимальным значением столбца 4. Однако, чтобы не усложнять ситуацию, первая идея уже будет очень полезна.
Каков диапазон интенсивности? 0=непрозрачный и 1=полностью прозрачный или наоборот?