Как построить такую ​​гистограмму с помощью gnuplot

Может ли кто-нибудь сказать мне, как построить такую ​​фигуру в Gnuplot? У меня есть три категории: A, B и C. У меня есть три подкатегории в каждой категории: SR1, SR0.8 и SR0.5. Для каждых SR1, SR 0.8 и SR0.5 у меня есть две переменные: SR1_L и SR1_R. Я хочу построить SR1_L и SR1_R на одном столбце, как показано на рисунке. Для SR1_L залейте сплошным цветом, а SR1_R — наклонной линией. Между SR1, SR0.8 и SR0.5 нет места, но для категорий A, B и C там есть место.

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

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

Category A:
SR1_L: 0.5    SR1_R:0.5
SR0.8_L: 0.6  SR0.8_R:0.4
SR0.5_L: 0.7   SR0.5_R:0.3

Category B:
SR1_L: 0.5    SR1_R:0.5
SR0.8_L: 0.6  SR0.8_R:0.4
SR0.5_L: 0.7   SR0.5_R:0.3

Category C:
SR1_L: 0.5    SR1_R:0.5
SR0.8_L: 0.6  SR0.8_R:0.4

Пожалуйста, отредактируйте свой вопрос, включив в него примеры данных, которые должны создать это представление. Сделайте так, чтобы читатели могли копировать/вставлять в свою среду. Используйте инструмент {} в меню «Правка» для выделенного мышью текста, чтобы добиться правильного code/data/output/errMsg форматирования. Удачи.

shellter 15.04.2024 05:41

Привет, Шеллтер, я не знаю, как сгенерировать эту цифру в gnuplot. Поэтому я рисую это в другом программном обеспечении. Я даже не знаю, как вводить данные в txt файл и есть ли какие-то требования. Я загружаю текстовый файл, содержащий исходные данные.

Edward 15.04.2024 08:28

@Эдвард, ты показываешь исходные данные, но есть ли у тебя гибкость в формате данных, чтобы минимизировать сложность с помощью команды построения графика? И всегда ли так SRx_L + SRx_R = 1? Почему SR0.5_ отсутствует последняя группа?

theozh 15.04.2024 09:23

Привет, Теож, связь SRx_L+SRx_R=1 есть всегда и с последней группой не было SR0.5_. Я еще раз отредактировал исходные данные

Edward 15.04.2024 11:02
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
4
128
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Этот вопрос напоминает мне следующий: Как создать гистограмму с накоплением строк и кластеризацией в gnuplot?, но как-то немного по-другому.

Возможно, есть способ использовать какой-то собственный стиль построения графиков gnuplot, требующий особого формата входных данных, но я бы начал с плоского списка. Вот предложение, которое должно быть достаточно общим, чтобы работать с разным количеством категорий, подкатегорий и подподкатегорий (например, «L», «R», «M», «K», ...).

Некоторые комментарии:

  • автоматически создавать списки уникальных предметов для категорий с помощью (неправильного) использования команды stats. Порядок указан в порядке первого появления. (проверьте help stats)

  • легче подвести итоги, если ваши данные находятся в массиве. Снова (ошибочное) использование команды stats для переноса данных из файла в массив. (проверьте help arrays)

  • использование стиля построения with boxxyerror обеспечивает максимальную гибкость (проверьте help boxxyerror)

  • keyentry используется для создания легенды (отметьте help keyentry)

  • Я специально изменил исходные данные, чтобы увидеть, есть ли разница между категориями.

Данные: SO78325960.dat

A   SR1     L   0.5
A   SR1     R   0.5
A   SR0.8   L   0.6
A   SR0.8   R   0.4
A   SR0.5   L   0.7
A   SR0.5   R   0.3
B   SR1     L   0.52
B   SR1     R   0.52
B   SR0.8   L   0.64
B   SR0.8   R   0.44
B   SR0.5   L   0.78
B   SR0.5   R   0.38
C   SR1     L   0.5
C   SR1     R   0.5
C   SR0.8   L   0.4
C   SR0.8   R   0.4

Скрипт:

### plot special barchart
reset session

FILE = "SO78325960.dat"
c0 = 1   # columns for L0,L1,L2
c1 = 2
c2 = 3
c3 = 4   # column for y-data

L0 = L1 = L2 = ''
addToList(list,col) = (_s=sprintf(' "%s"',strcol(col)), strstrt(list,_s) ? '' : _s)
stats FILE u (L0=L0.addToList(L0,c0), L1=L1.addToList(L1,c1), L2=L2.addToList(L2,c2)) nooutput
N0         = words(L0)
N1         = words(L1)
N2         = words(L2)
Ngap       = 1
myBoxwidth = 0.8

PosX0(n0)        = n0*(N1+Ngap) + (N1-1)/2.
PosX1(n0,n1)     = n0*(N1+Ngap) + n1
myPattern(n)     = word("3 6 2 7", n)
Filter(n0,n1,n2) = strcol(c0) eq word(L0,n0+1) && strcol(c1) eq word(L1,n1+1) && strcol(c2) eq word(L2,n2)

array A[N0*N1*N2]
set table $Dummy
    plot for [n0=0:N0-1] for [n1=0:N1-1] for [n2=1:N2] FILE \
        u ($0==0 ? (i=n0*N1*N2+n1*N2+n2, A[i]=0) : 0, Filter(n0,n1,n2) ? A[i]=column(c3) : 0) w table
unset table
undef $Dummy

set offsets 0.5,0.5, graph 0.05,0
set yrange[0:]
set xtics out
set style fill solid 0.3
set key out noautotitle noenhanced
set for [i=0:N0-1] xtic (word(L0,i+1) PosX0(i))
set xrange[-0.5:]

plot for [n0=0:N0-1] for [n1=0:N1-1] for [n2=1:N2] '+' every ::::0 \
         u (PosX1(n0,n1)):(y0=A[n0*N1*N2+n1*N2+n2]/2., y0 + sum[i=1:n2-1] A[n0*N1*N2+n1*N2+i]): \
         (myBoxwidth/2.):(y0) w boxxy lc n1+1 fill pattern myPattern(n2), \
     for [n1=1:N1] for [n2=1:N2] keyentry w boxes lc n1 fill pattern myPattern(n2) ti sprintf("%s_%s",word(L1,n1), word(L2,n2))
### end of script

Результат:

Спасибо, теож. Этот сценарий полезен. Кстати, есть ли способ уменьшить расстояние между подкатегорией А до нуля?

Edward 21.04.2024 14:36

@Эдвард, да, конечно. Просто измените строку на myBoxwidth=1.0. Задача решена? Ответ на вопрос?

theozh 21.04.2024 18:45

Да, спасибо, теож. Действительно очень помогает

Edward 22.04.2024 06:38

@Эдвард рад это слышать. Если это было полезно, пожалуйста, проголосуйте за него, и если это ответило на ваш вопрос, пожалуйста, примите ответ, указав, что на вопрос дан ответ и ваша проблема решена.

theozh 22.04.2024 08:39

Это ответ с использованием «гистограммы с накоплением столбцов».

Во-первых, нам нужно рассмотреть расположение данных. Поскольку gnuplot считывает и обрабатывает файлы данных построчно, gnuplot очень сложно напрямую обрабатывать ваш формат данных. Для этого ответа я подготовил следующий формат данных.

# A
SR1 SR0.8 SR0.5
0.5 0.6 0.7
0.5 0.4 0.3


# B
SR1 SR0.8 SR0.5
0.5 0.6 0.7
0.5 0.4 0.3


# C
SR1 SR0.8 SR0.5
0.5 0.6 ?
0.5 0.4 ?

Данные разделены на три блока с двойными пустыми строками, и вы можете выбрать данные категории А, указав index 'A' в команде графика. Давайте продолжим использовать стратегию рисования этих данных с помощью «гистограмм со столбцами».

На вашем рисунке данные L заполнены сплошным цветом, а данные R заполнены штриховкой. Поскольку смешивать сплошной цвет и штрихованный узор было сложно, я решил заполнить все коробки сплошными цветами. Я изменю цветовую серию следующим образом.

set linetype 1 lc rgb "#ff0000" 
set linetype 2 lc rgb "#ff8080"
set linetype 3 lc rgb "#00ff00" 
set linetype 4 lc rgb "#80ff80"
set linetype 5 lc rgb "#0000ff" 
set linetype 6 lc rgb "#8080ff"
set linetype cycle 6

Следующая функция предназначена для выбора соответствующего цвета для каждого поля.

array category2 = ["SR1", "SR0.8", "SR0.5"].
CN(c,n) = 2*index(category2,c) - 1 + n

Эта функция работает следующим образом

print CN("SN1",0)   #=> 1
print CN("SN1",1)   #=> 2
print CN("SN0.8",0) #=> 3
print CN("SN0.8",1) #=> 4
print CN("SN0.5",0) #=> 5
print CN("SN0.5",1) #=> 6

Наконец, вот скрипт, созданный путем объединения вышеуказанных элементов.

#
# Rearranged data
#
$data << EOD
# A
SR1 SR0.8 SR0.5
0.5 0.6 0.7
0.5 0.4 0.3


# B
SR1 SR0.8 SR0.5
0.5 0.6 0.7
0.5 0.4 0.3


# C
SR1 SR0.8 SR0.5
0.5 0.6 ?
0.5 0.4 ?
EOD

#
# Redefinition of linetype sequence
#
set linetype 1 lc rgb "#ff0000" 
set linetype 2 lc rgb "#ff8080"
set linetype 3 lc rgb "#00ff00" 
set linetype 4 lc rgb "#80ff80"
set linetype 5 lc rgb "#0000ff" 
set linetype 6 lc rgb "#8080ff"
set linetype cycle 6

#
# Axis settings
#
set tmargin screen 0.9
set bmargin screen 0.2
set border 3
set xtics offset 0,0.5 scale 1 out nomirror 
set yrange [0:1.2] 
set ytics 0,0.1,1 out nomirror
set key out noenhanced

#
# Histogram settings
#
set style data histograms
set style histogram columnstacked
set style fill solid 0.7 border lc "black"
set boxwidth 0.8

#
# Datafile settings
#
set datafile columnheader

#
# Support function
#
array category2 = ["SR1", "SR0.8", "SR0.5"]
CN(c,n) = 2*index(category2,c) - 1 + n

#
# Plot command
#
plot newhistogram "A", \
     c = "SR1"   $data i "A" u c:(CN(c,$0)) lc var t columnhead, \
     c = "SR0.8" $data i "A" u c:(CN(c,$0)) lc var t columnhead, \
     c = "SR0.5" $data i "A" u c:(CN(c,$0)) lc var t columnhead, \
     newhistogram "B", \
     c = "SR1"   $data i "B" u c:(CN(c,$0)) lc var t columnhead, \
     c = "SR0.8" $data i "B" u c:(CN(c,$0)) lc var t columnhead, \
     c = "SR0.5" $data i "B" u c:(CN(c,$0)) lc var t columnhead, \
     newhistogram "C", \
     c = "SR1"   $data i "C" u c:(CN(c,$0)) lc var t columnhead, \
     c = "SR0.8" $data i "C" u c:(CN(c,$0)) lc var t columnhead, \
     c = "SR0.5" $data i "C" u c:(CN(c,$0)) lc var t columnhead, \
     c = "SR1"   keyentry w boxes fs s 0.5 lc CN(c,0) t c."_L", \
     c = "SR1"   keyentry w boxes fs s 0.5 lc CN(c,1) t c."_R", \
     c = "SR0.8" keyentry w boxes fs s 0.5 lc CN(c,0) t c."_L", \
     c = "SR0.8" keyentry w boxes fs s 0.5 lc CN(c,1) t c."_R", \
     c = "SR0.5" keyentry w boxes fs s 0.5 lc CN(c,0) t c."_L", \
     c = "SR0.5" keyentry w boxes fs s 0.5 lc CN(c,1) t c."_R"

Команда сюжета довольно многословна, но она может сгенерировать следующий рисунок.

Другие вопросы по теме