Генерация пустого сейсмического трехстороннего графика

4

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

tripartite graph

Как я могу создать пустой трехсторонний сейсмический график? Насколько я знаю, Excel не имеет этой функциональности, так как вам нужно иметь возможность построить четыре отдельные оси в 2D с двумя осями под углом. Все оси в логарифмическом масштабе.

Система единиц должна быть такой:

  • Спектральное смещение: дюймы
  • Спектральная скорость: в / сек
  • Спектральное ускорение:% от $ g $
  • Частота: Гц

В противном случае ссылка на график с высоким разрешением будет приемлемой.

grfrazee
источник
Может быть, вы должны построить это самостоятельно в TikZ (Латекс).
Karlo
@ Карло, если бы я знал, как это сделать, я бы попробовал. Мои знания LaTeX довольно скудны, а мой TikZ еще меньше.
grfrazee
@ Карло, я открыл вопрос по tex.SE и для этого тоже.
grfrazee

Ответы:

2

Вы можете попробовать запустить следующий R скрипт, который выдает рисунок ниже. tripartite graph paper

require(ggplot2)
require(data.table)

# The constant value grid lines
freqs = unique(c(seq(0.1, 0.2, by = 0.05), seq(0.2, 1.0, by = 0.1),
      seq(1.0, 2.0, by = 0.50), seq(2.0, 10.0, by = 1.0),
      seq(10.0, 20.0, by = 5.0), seq(20.0, 100.0, by = 10.0),
      seq(100.0, 200.0, by = 50.0), seq(200.0, 1000.0, by = 100.0)))
vels = unique(c(seq(1.0, 2.0, by = 0.50), seq(2.0, 10.0, by = 1.0),
      seq(10.0, 20.0, by = 5.0), seq(20.0, 100.0, by = 10.0),
      seq(100.0, 200.0, by = 50.0), seq(200.0, 1000.0, by = 100.0)))
accs = unique(c(seq(0.001, 0.002, by = 0.0005), seq(0.002, 0.01, by = 0.001),
      seq(0.01, 0.02, by = 0.005), seq(0.02, 0.1, by = 0.01),
      seq(0.1, 0.2, by = 0.05), seq(0.2, 1.0, by = 0.1),
      seq(1.0, 2.0, by = 0.50), seq(2.0, 10.0, by = 1.0),
      seq(10.0, 20.0, by = 5.0), seq(20.0, 100.0, by = 10.0),
      seq(100.0, 200.0, by = 50.0), seq(200.0, 1000.0, by = 100.0),
      seq(1000.0, 2000.0, by = 500.0), seq(2000.0, 10000.0, by = 1000.0)))
disps = unique(c(seq(0.0001, 0.0002, by = 0.00005), seq(0.0002, 0.001, by = 0.0001),
          seq(0.001, 0.002, by = 0.0005), seq(0.002, 0.01, by = 0.001),
          seq(0.01, 0.02, by = 0.005), seq(0.02, 0.1, by = 0.01),
          seq(0.1, 0.2, by = 0.05), seq(0.2, 1.0, by = 0.1),
          seq(1.0, 2.0, by = 0.50), seq(2.0, 10.0, by = 1.0),
          seq(10.0, 20.0, by = 5.0), seq(20.0, 100.0, by = 10.0),
          seq(100.0, 200.0, by = 50.0), seq(200.0, 1000.0, by = 100.0),
          seq(1000.0, 2000.0, by = 500.0), seq(2000.0, 10000.0, by = 1000.0)))

# Horizontal grid lines (const vel = in/s)
vel_grid = data.table()
freqmin = min(freqs)
freqmax = max(freqs)
for (vel in vels) {
  xx = c(freqmin, freqmax)
  yy = c(vel, vel)
  label = c(paste0("vel",vel), paste0("vel",vel)) 
  color = "vel"
  local_dt = data.table(x = xx, y = yy, label = label, color = color)
  vel_grid = rbind(vel_grid, local_dt)
}

# Vertical grid lines (freq = cycles/sec)
freq_grid = data.table()
velmin = min(vels)
velmax = max(vels)
for (freq in freqs) {
  xx = c(freq, freq)
  yy = c(velmin, velmax)
  label = c(paste0("freq",freq), paste0("freq",freq)) 
  color = "freq"
  local_dt = data.table(x = xx, y = yy, label = label, color = color)
  freq_grid = rbind(freq_grid, local_dt)
}

# -45 grid lines (constant acc = omega * vel = (2*pi*freq) radians/sec * vel in/sec  
#                              = (2*pi*freq)*vel in/sec^2 = (2*pi*freq)*vel/g  Gs)
gravity = 32.2*12.0  # in/s^2
acc_grid = data.table()
for (acc in accs) {
  for (freq in freqs) {
    f = freq
    vel = acc*gravity/(freq*2*pi)
    if (vel < velmin) {
      vel = velmin
      f = acc*gravity/(vel*2*pi)
    }
    if (vel > velmax) {
      vel = velmax
      f = acc*gravity/(vel*2*pi)
    }
    xx = c(f)
    yy = c(vel)
    label = c(paste0("acc",acc)) 
    color = "acc"
    local_dt = data.table(x = xx, y = yy, label = label, color = color)
    acc_grid = rbind(acc_grid, local_dt)
  }
}

## The const acc=1 line is the disp axis
acc_1 = acc_grid[acc_grid$label == "acc1"]
disp_axis = data.table()
for (disp in disps) {
  acc = 1.2
  omega = sqrt(acc*gravity/disp)
  freq = omega/(2*pi)
  vel = omega*disp
  xx = c(freq)
  yy = c(vel)
  label = c(paste0("disp_axis",acc)) 
  color = "disp_axis"
  local_dt = data.table(x = xx, y = yy, z = disp, label = label, color = color)
  disp_axis = rbind(disp_axis, local_dt)
}

# +45 grid lines (const disp = vel/omega = vel/(2*pi*freq) in)
disp_grid = data.table()
for (disp in disps) {
  for (freq in freqs) {
    f = freq
    vel = disp*freq*(2*pi)
    if (vel < velmin) {
      vel = velmin
      f = vel/(disp*2*pi)
    }
    if (vel > velmax) {
      vel = velmax
      f = vel/(disp*2*pi)
    }
    xx = c(f)
    yy = c(vel)
    label = c(paste0("disp",disp)) 
    color = "disp"
    local_dt = data.table(x = xx, y = yy, label = label, color = color)
    disp_grid = rbind(disp_grid, local_dt)
  }
}

## The const disp=0.1 line is the acc axis
disp_1 = disp_grid[disp_grid$label == "disp0.1"]
acc_axis = data.table()
for (acc in accs) {
  disp = 0.12
  omega = sqrt(acc*gravity/disp)
  freq = omega/(2*pi)
  vel = omega*disp
  xx = c(freq)
  yy = c(vel)
  label = c(paste0("acc_axis",acc)) 
  color = "acc_axis"
  local_dt = data.table(x = xx, y = yy, z = acc, label = label, color = color)
  acc_axis = rbind(acc_axis, local_dt)
}

# Join vertical and horizontal
grid = rbind(vel_grid, freq_grid, acc_grid, disp_grid)

### Axis label points
disp = 0.08
acc = 1000
omega = sqrt(acc*gravity/disp)
freq = omega/(2*pi)
vel = omega*disp
acc_axis_label = data.table(x = c(freq), y = c(vel), label="Spectral acceleration (g)")

disp = 200
acc = 0.8
omega = sqrt(acc*gravity/disp)
freq = omega/(2*pi)
vel = omega*disp
disp_axis_label = data.table(x = c(freq), y = c(vel), label="Spectral displacement (in)")

# Plot horizontal grid
xticks = freqs[c(TRUE, FALSE)]
yticks = vels[c(TRUE, FALSE)]

plt = ggplot() +
      geom_line(data = grid, aes(x = x, y = y, group = label, color = color),
                size=0.25) +
      geom_line(data = acc_1, aes(x = x, y = y), color = 1, size=0.5) + 
      geom_line(data = disp_1, aes(x = x, y = y), color = 1, size=0.5) + 
      xlab("Frequency (Hz)") + 
      ylab("Spectral velocity (in/sec)") + 
      scale_color_discrete(guide = FALSE) +
      scale_x_log10(limits = c(freqmin, freqmax),
                    expand = c(0,0),
                    breaks=xticks,
                    labels= c("0.1","0.2","0.4","0.6","0.8", xticks[xticks >= 1])) +
      scale_y_log10(limits = c(velmin, velmax),
                    expand = c(0,0),
                    breaks=yticks) +
      coord_fixed() +
      theme_bw() +
      theme(panel.grid.major = element_blank(),
            panel.grid.minor = element_blank()) +
      annotate("text", x = acc_axis$x, y = acc_axis$y, label = as.character(acc_axis$z), 
               size = 3, angle = -45) + 
      annotate("text", x = disp_axis$x, y = disp_axis$y, label = as.character(disp_axis$z), 
               size = 3, angle = 45)  +
      annotate("text", x = acc_axis_label$x, y = acc_axis_label$y, label = acc_axis_label$label,
               size = 4, angle = 45)  +
      annotate("text", x = disp_axis_label$x, y = disp_axis_label$y, label = disp_axis_label$label,
               size = 4, angle = -45) 
print(plt)
ggsave("seismic_tripartite_paper1.pdf")
Biswajit Banerjee
источник
Отлично. Это примерно то, что я искал.
grfrazee
@grfrazee Затем вы можете принять ответ, чтобы вопрос был удален из списка без ответа.
Biswajit Banerjee
1
Я хорошо знаю, как здесь работает Вопрос. Вы можете быть уверены, что я приму ответ, когда у меня все будет хорошо и готово сделать это.
grfrazee
Тогда я предполагаю, что мой ответ не совсем то, что вы ищете. Не могли бы вы объяснить, что именно вы ищете?
Biswajit Banerjee
Существует несколько способов решения проблемы. У кого-то еще может быть решение, отличное от вашего, и оно может быть полезным для меня или кого-то еще. Принятие твоего сейчас отвлечет других, у которых может быть другой ответ.
grfrazee
2

Tripartite Paper - Period on X-axis Это единственное место в Интернете, где я мог найти изображения с приличным разрешением для трехсторонней печати. Тем не менее, у него были некоторые ограничения, которые влияли на использование в нашей области: 1) проектные землетрясения достигают максимума в нашей области примерно 1 г и 2) мы, как правило, имеем дело только с периодами от 0,01 до 10 с или от 0,1 до 100 Гц. Это привело к участкам землетрясения, втиснутым в один угол, и 144-летнее землетрясение с операционной базой почти не обнаружилось. Кроме того, мы обычно строим график с периодом, а не частотой, по оси X.

Я взял выходные, чтобы изучить достаточно R, чтобы изменить превосходный сценарий Бисваджита Банерджи, чтобы придумать сюжет, который бы служил моим целям. Я собираюсь бросить это в случае, если это полезно для кого-либо еще. Если вы не работали с R, вы можете установить базовый интерпретатор R, вырезать и вставить код Мистера Банерджи или мой в скрипт и запустить его, чтобы получить более качественный вывод PDF.

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

require(ggplot2)
require(data.table)

# The constant value grid lines
periods = unique(c(seq(0.01, 0.02, by = 0.005), seq(0.02, 0.1, by = 0.01),
      seq(0.1, 0.2, by = 0.05), seq(0.2, 1.0, by = 0.1),
      seq(1.0, 2.0, by = 0.50), seq(2.0, 10.0, by = 1.0)))
vels = unique(c(seq(0.01, 0.02, by = 0.005), seq(0.02, 0.1, by = 0.01),
    seq(0.1, 0.2, by = 0.05), seq(0.2, 1.0, by = 0.1),
    seq(1.0, 2.0, by = 0.50), seq(2.0, 10.0, by = 1.0),
      seq(10.0, 20.0, by = 5.0)))
accs = unique(c(seq(0.0001, 0.0002, by = 0.00005),
    seq(0.0002, 0.001, by = 0.0001),
    seq(0.001, 0.002, by = 0.0005), seq(0.002, 0.01, by = 0.001),
      seq(0.01, 0.02, by = 0.005), seq(0.02, 0.1, by = 0.01),
      seq(0.1, 0.2, by = 0.05), seq(0.2, 1.0, by = 0.1),
      seq(1.0, 2.0, by = 0.50), seq(2.0, 10.0, by = 1.0),
      seq(10.0, 20.0, by = 5.0), seq(20.0, 100.0, by = 10.0)))
disps = unique(c(seq(0.00001, 0.00002, by = 0.000005), seq(0.00002, 0.0001, by = 0.00001),
          seq(0.0001, 0.0002, by = 0.00005), seq(0.0002, 0.001, by = 0.0001),
          seq(0.001, 0.002, by = 0.0005), seq(0.002, 0.01, by = 0.001),
          seq(0.01, 0.02, by = 0.005), seq(0.02, 0.1, by = 0.01),
          seq(0.1, 0.2, by = 0.05), seq(0.2, 1.0, by = 0.1),
          seq(1.0, 2.0, by = 0.50), seq(2.0, 10.0, by = 1.0),
          seq(10.0, 20.0, by = 5.0)))

# Horizontal grid lines (const vel = in/s)
vel_grid = data.table()
periodmin = min(periods)
periodmax = max(periods)
for (vel in vels) {
  xx = c(periodmin, periodmax)
  yy = c(vel, vel)
  label = c(paste0("vel",vel), paste0("vel",vel)) 
  color = "vel"
  local_dt = data.table(x = xx, y = yy, label = label, color = color)
  vel_grid = rbind(vel_grid, local_dt)
}

# Vertical grid lines (freq = cycles/sec)
period_grid = data.table()
velmin = min(vels)
velmax = max(vels)
for (period in periods) {
  xx = c(period, period)
  yy = c(velmin, velmax)
  label = c(paste0("period",period), paste0("period",period)) 
  color = "period"
  local_dt = data.table(x = xx, y = yy, label = label, color = color)
  period_grid = rbind(period_grid, local_dt)
}

# 45 grid lines (constant acc = omega * vel = (2*pi/period) radians/sec * vel in/sec  
#                              = (2*pi/period)*vel in/sec^2 = (2*pi/period)*vel/g  Gs)
gravity = 32.2*12.0  # in/s^2
acc_grid = data.table()
for (acc in accs) {
  for (period in periods) {
    Ts = period
    vel = acc*gravity*period/(2*pi)
    if (vel < velmin) {
      vel = velmin
      Ts = vel*2*pi/(acc*gravity)
    }
    if (vel > velmax) {
      vel = velmax
      Ts = vel*2*pi/(acc*gravity)
    }
    xx = c(Ts)
    yy = c(vel)
    label = c(paste0("acc",acc)) 
    color = "acc"
    local_dt = data.table(x = xx, y = yy, label = label, color = color)
    acc_grid = rbind(acc_grid, local_dt)
  }
}

## The const acc=1 line is the disp axis
acc_1 = acc_grid[acc_grid$label == "acc0.01"]
disp_axis = data.table()
for (disp in disps) {
  acc = 0.012
  omega = sqrt(acc*gravity/disp)
  period = (2*pi)/omega
  vel = omega*disp
  xx = c(period)
  yy = c(vel)
  label = c(paste0("disp_axis",acc)) 
  color = "disp_axis"
  local_dt = data.table(x = xx, y = yy, z = disp, label = label, color = color)
  disp_axis = rbind(disp_axis, local_dt)
}

# -45 grid lines (const disp = vel/omega = vel/(2*pi/period) in)
disp_grid = data.table()
for (disp in disps) {
  for (period in periods) {
    Ts = period
    vel = disp*(2*pi)/period
    if (vel < velmin) {
      vel = velmin
      Ts = disp*2*pi/vel
    }
    if (vel > velmax) {
      vel = velmax
      Ts = disp*2*pi/vel
    }
    xx = c(Ts)
    yy = c(vel)
    label = c(paste0("disp",disp)) 
    color = "disp"
    local_dt = data.table(x = xx, y = yy, label = label, color = color)
    disp_grid = rbind(disp_grid, local_dt)
  }
}

## The const disp=0.1 line is the acc axis
disp_1 = disp_grid[disp_grid$label == "disp0.1"]
acc_axis = data.table()
for (acc in accs) {
  disp = 0.12
  omega = sqrt(acc*gravity/disp)
  period = 2*pi/omega
  vel = omega*disp
  xx = c(period)
  yy = c(vel)
  label = c(paste0("acc_axis",acc)) 
  color = "acc_axis"
  local_dt = data.table(x = xx, y = yy, z = acc, label = label, color = color)
  acc_axis = rbind(acc_axis, local_dt)
}

# Join vertical and horizontal
grid = rbind(vel_grid, period_grid, acc_grid, disp_grid)

### Axis label points
disp = 0.08
acc = 0.002
omega = sqrt(acc*gravity/disp)
period = 2*pi/omega
vel = omega*disp
acc_axis_label = data.table(x = c(period), y = c(vel), label="Spectral acceleration (g)")

disp = 0.006
acc = 0.008
omega = sqrt(acc*gravity/disp)
period = 2*pi/omega
vel = omega*disp
disp_axis_label = data.table(x = c(period), y = c(vel), label="Spectral displacement (in)")

# Plot horizontal grid
xticks = periods[c(TRUE, FALSE)]
yticks = vels[c(TRUE, FALSE)]


plt = ggplot() +
      geom_line(data = grid, aes(x = x, y = y, group = label, color = color),
                size=0.25) +
      geom_line(data = acc_1, aes(x = x, y = y), color = 1, size=0.5) + 
      geom_line(data = disp_1, aes(x = x, y = y), color = 1, size=0.5) + 
      xlab("Period (s)") + 
      ylab("Spectral velocity (in/sec)") + 
      scale_color_discrete(guide = FALSE) +
      scale_x_log10(limits = c(periodmin, periodmax),
                    expand = c(0,0),
                    breaks=xticks,
                    labels= c("0.01","0.02","0.04","0.06","0.08", xticks[xticks >= 0.1])) +
      scale_y_log10(limits = c(velmin, velmax),
                    expand = c(0,0),
                    breaks=yticks) +
      coord_fixed() +
      theme_bw() +
      theme(panel.grid.major = element_blank(),
            panel.grid.minor = element_blank()) +
      annotate("text", x = acc_axis$x, y = acc_axis$y, label = as.character(acc_axis$z), 
               size = 3, angle = 45) + 
      annotate("text", x = disp_axis$x, y = disp_axis$y, label = as.character(disp_axis$z), 
               size = 3, angle = -45)  +
      annotate("text", x = acc_axis_label$x, y = acc_axis_label$y, label = acc_axis_label$label,
               size = 4, angle = -45)  +
      annotate("text", x = disp_axis_label$x, y = disp_axis_label$y, label = disp_axis_label$label,
               size = 4, angle = 45)

print(plt)
ggsave("TripartitePaper.pdf",width = 10.0, height = 10.0, units = "in")
CatCube
источник