gnuplot с ломаной осью x в v5.2 с использованием нелинейных - PullRequest
0 голосов
/ 31 августа 2018

Версия 5.2 содержит set nonlinear. Можно использовать его для построения ломаных осей, как это предлагается в демоверсии здесь . Я пытаюсь выполнить шаги для оси X также логарифмические. Текущий код ниже, а также данные. Проблема, которую я не могу понять, - это масштабирование первого порядка после перерыва, это показано на этом графике: enter image description here

Как видите, проблема между 0,1 и 1. Что я делаю не так?

data="test2.txt"
unset nonlinear x
x1min=1e-6
x1max=1e-5
x2min=1e-1
x2max=1e+3
ymin =1e-1
ymax =1e+3
dx=(x2min - x1max)
set yrange  [ymin:ymax]
unset key
set format x "10^{%T}
set xtics font ",12"
set ytics font ",12"
set y2tics font ",12"
axis_gap=1
f(x) = (x <= x1max)  ? log10(x) : (x < x2min)            ? NaN : log10(x - dx + axis_gap)
g(x) = (x <= x1max) ? 10**x     : (x < x1max + axis_gap) ? NaN : 10**(x + dx - axis_gap)
set xrange  [x1min:x2max] nereverse nowriteback
set nonlinear x  via f(x) inverse g(x)
set logscale y
set xtics  (1e-6 0,2e-6 1,3e-6 1,4e-6 1,5e-6 1,6e-6 1,7e-6 1,8e-6 1,9e-6 1,1e-5 0,2e-5 1,3e-5 1,4e-5 1,5e-5 1,6e-5 1,7e-5 1,8e-5 1,9e-5 1,1e-2 0,2e-2 1,3e-2 1,4e-2 1,5e-2 1,6e-2 1,7e-2 1,8e-2 1,9e-2 1,1e-1 0,2e-1 1,3e-1 1,4e-1 1,5e-1 1,6e-1 1,7e-1 1,8e-1 1,9e-1 1,1 0,2 1,3 1,4 1,5 1,6 1,7 1,8 1,9 1,10 0,20 1,30 1,40 1,50 1,60 1,70 1,80 1,90 1,100 0,200 1,300 1,400 1,500 1,600 1,700 1,800 1,900 1,1000 0)
plot data u 1:2

где данные:

5 0.471238898038469
4.18879020478639e-6 0.7
4.18879020478639e-6 2
4.18879020478639e-6 8.8
4.18879020478639e-6 2.8
1 4.18879020478639e-6
1 4.18879020478639e-6
98.174770424681 1.68
98.174770424681 3.4
0.125663706143592 161.809725
0.125663706143592 425.60861
0.125663706143592 425.60861
0.125663706143592 425.60861
0.125663706143592 483.467845
144 43.14926
1 50.99458
1 51.975245
1 52.95591
1 54.91724
1 57.859235
1 66.68522
1 69.627215
1 78.4532
1.728 32.361945
1.728 40.207265
1.728 41.18793
1.728 43.14926
1.728 45.11059
1.728 48.052585
1.728 54.91724
1.728 65.704555
3.375 46.091255
3.375 50.99458
3.375 54.91724
3.375 56.87857
3.375 57.859235
3.375 64.72389
8 24.516625
8 43.14926
8 46.091255
8 51.975245
8 54.91724
8 59.820565
15.625 47.07192
15.625 48.052585
15.625 50.99458
15.625 52.95591
15.625 55.897905
64 42.168595
64 42.168595
64 48.052585
125 35.30394
125 42.168595
125 50.013915

UPDATE

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

unset key
unset nonlinear x
unset nonlinear x2
axis_gap=1
x1min=1
x1max=3
x2min=5
x2max=20
ymin =1e-1
ymax =1e+3
dx=(x2min - x1max)
x1minp=log10(x1min)
x1maxp=log10(x1max)
x2minp=log10(x2min)
x2maxp=log10(x2max)
set yrange  [ymin:ymax]
set xrange  [x1min:x2max] noreverse nowriteback
f(x) = (x <= x1max) ? log10(x) : (x < x2min) ? NaN : log10(x/(x2min/x1max)*axis_gap)
g(x) = (x <= x1maxp) ? 10**(x) : (x < log10(x1max*axis_gap)) ? NaN :  10**(x) + dx + log10(axis_gap)
set nonlinear x  via f(x) inverse g(x)
set logscale y
set xtics (1e0 0,2e0 0,3e0 0,4e0 0,5e0 0,6e0 0,7e0 0,8e0 0,9e0 0,1e1 0,2e1 0)
plot 0 w l

В этой версии я наконец-то получил понятие nonlinear, и я, скорее, думаю, с точки зрения расстояния от отметки до начала координат (невидимой оси gnuplot), которое определяется f (x), где x - числа из выбранный диапазон и f(x) - это тот, который находится в set nonlinear x via f(x) inverse g(x), а g(x) получает число, связанное с отметкой в ​​позиции x от начала координат (число, которое вводится в y(x) y, нанесенное на y- ось и отображается на оси х выше / ниже галочки). Это может показаться сложным, потому что я считаю, что это намного лучше, чем концепция нелинейных видимых и линейных невидимых осей, при условии, что я действительно понимаю это правильно на этот раз.

Решение должно не только работать без warning: could not confirm linked axis inverse mapping function на обоих образцах, но также должно быть объяснение, что не так с функциями в этом обновлении, в идеале с точки зрения расстояний и чисел, как предложено выше, а не видимых / невидимых гнуплот жаргон.

Обновление 2

Я тоже это заметил, см. Картинки.

f(x) = (x <= x1max) ? log10(x) : (x < x2min) ? NaN : log10(x/(x2min/x1max)*axis_gap)
g(x) = (x <= x1maxp) ? 10**(x) : (x < log10(x1max*axis_gap)) ? NaN :  10**(x*(x2min/x1max)) + dx + log10(axis_gap)

Вы можете видеть, что координаты, отображаемые в левом нижнем углу окна, ведут себя, как и ожидалось (axis_gap=1.1), но имеют метки (и если вы строите точки данных (1 1, 2 1, 3 1, 5 1, 6 1) , ...)) имеют неправильное размещение): enter image description here enter image description here

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

Исправленный ответ:

Посмотрите документацию по gnuplot:

[новая команда в версии 5.2] Эта команда похожа на установленную ссылку кроме того, что видна только одна из двух связанных осей. скрытая ось остается линейной. Координаты вдоль видимой оси сопоставляется путем применения g(x) к скрытым координатам оси. f(x) наносит на карту координаты видимой оси обратно на скрытую линейную ось.

Пример:

set xrange [1:1000]

set nonlinear x via log10(x) inverse 10**x

Это Пример устанавливает логарифмическую ось х. Это альтернативный способ достижение эффекта set log x. Скрытая ось в этом случае имеет range [0:3], полученный расчетом [log10(xmin):log10(xmax)]. Вы должен предоставить как прямое, так и обратное выражение.

Другими словами: f(x) - это функция, которая принимает ваше входное значение x-данных и отображает его в линейном диапазоне. Если у вас set logscale x, у вас уже есть такое отображение, и функция f(x) просто log10(x). И g(x) - обратная функция 10**x

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

enter image description here

Диапазон от x1max до x2min, который вы хотите опустить, сжимается функцией f(x) в диапазон от x1max до BrokenAxisPos (я установил его на 1e-4). Требуется небольшой расчет, чтобы получить правильные множители функции f(x). Для значений выше x2min функция f (x) смещает исходное значение x на некоторое подходящее значение. И после некоторых небольших вычислений g (x) является обратной функцией f (x).

С кодом:

### broken nonlinear (logarithmic) axis
reset session
set size square 

data="test2.txt"

x1min=1e-6; x1max=1e-5
x2min=1e-1; x2max=1e+3
ymin =1e-1; ymax =1e+3
unset key

# settings x-axis
unset logscale x
set xrange[x1min:x2max]
set format x "10^{%T}"
set xtics font ",12"
# manually set major xtics
set xtics add ("0.1" 1e-1, "1" 1, "10" 10, "100" 100, "1000" 1000)
set mxtics 10
# settings y-axis
set logscale y
set format y "%g"
set yrange  [ymin:ymax]
set ytics font ",12"

set grid xtics, ytics

BrokenAxisPos = 1e-4
m = log10(BrokenAxisPos/x1max)/log10(x2min/x1max)
f(x) = (x <= x1max) ? log10(x) : x<x2min ? log10(x1max**(1-m)*x**m) : log10(x*BrokenAxisPos/x2min)
g(x) = (x <= log10(x1max)) ? 10**x : x<log10(BrokenAxisPos) ? (10**x/x1max**(1-m))**(1/m) : (x2min/BrokenAxisPos)*10**x

set nonlinear x via f(x) inverse g(x)

# manually hide x1,x2 axis and y-gridlines by placing a rectangle
set obj 1 rect from x1max*1.2, graph 0 to x2min*0.8, graph 1 fs solid 1.0 border bgnd front

plot data u 1:2 w p
### end of code

Кстати, вы также можете использовать прерывистые функции, установив "gap" -part в NaN, как вы и @Ethan. Тогда вы можете просто пропустить расчет и использовать m.

f(x) = (x <= x1max) ? log10(x) : x<x2min ? NaN : log10(x*BrokenAxisPos/x2min)
g(x) = (x <= log10(x1max)) ? 10**x : x<log10(BrokenAxisPos) ? NaN : (x2min/BrokenAxisPos)*10**x

Но тогда вам придется адаптировать сокрытие осей от

set obj 1 rect from x1max*1.2, graph 0 to x2min*0.8, graph 1 fs solid 1.0 border bgnd front

до

set obj 1 rect from x1max, graph 0 to x2min, graph 1 fs solid 1.0 border bgnd front

, поскольку x1max*1.2 и x2min*0.8 (которые используются для отображения линии x-grid) будут сопоставлены с NaN.

С непрерывными f(x) и g(x) вы получите результат:

enter image description here

0 голосов
/ 31 августа 2018

Логическая ошибка в вашем подходе заключается в том, что для сдвига по оси логарифмического масштаба вам нужно умножить или разделить на смещение, а не складывать или вычитать. Таким образом, ваше отображение будет примерно таким:

axis_gap = 1.e4
f(x) = (x <= x1max)  ? log10(x) : (x < x2min)            ? NaN : log10( (x/dx) / axis_gap)
g(x) = (x <= x1max) ? 10**x     : (x < x1max + axis_gap) ? NaN : 10**( (x*dx) * axis_gap)

получая рисунок ниже enter image description here

...