Если смотреть на карты океана широко, быстро понимаешь: «зерно» наблюдений определяет, что мы вообще способны увидеть. Масштаб меняет саму формулировку вопросов, — и редкая сетка EN4 в Баренцевом море порой даёт не «карту», а грубую мозаику. Ресэмплинг — это наш способ подружить масштаб и видимость: мы увеличиваем пространственное разрешение растра и интерполируем значения, чтобы получить непрерывную поверхность, пригодную для изолиний и анализа.
Важно не перепутать ясность с иллюзией знания. Ум любит гладкие картинки и готов принять их за истину; по мир полон неожиданностей, и интерполяция не создаёт новых данных, а лишь аккуратно «зашивает» пустоты. Всегда держим критерий хорошего объяснения: метод должен быть воспроизводимым, проверяемым и не обещать лишнего. В этом скрипте выбран билинейный ресэмплинг как честный компромисс между сглаживанием и сохранением крупных структур: визуализация становится читабельной, а исходная информативность не «приписывается задним числом».
Подход эволюционен и прагматичен — выживает не «самая умная» интерполяция, а та, что лучше служит цели карты и не вносит артефактов. Мы задаём область (Баренцево море), собираем растровую поверхность из точек в WGS84, формируем целевую сетку с более тонким шагом, интерполируем, категоризируем значения по осмысленным бинам и строим итоговую карту: растровая подложка, изолинии, координатная сетка, береговая линия. Геометрия и проекции названы своими именами, а не «растворены» в красивой картинке.
Методологический оптимизм уместен, но дисциплинирован: систематическая, воспроизводимая обработка действительно делает нас лучше, если помнить границы. Для строгих расчётов держим нативное разрешение; для картографирования — используем сглаженную сетку. Если исходная сетка слишком редка, тестируем альтернативы (бикубика, IDW, сплайны, кригинг) и выбираем то, что минимизирует артефакты. Это ровно тот случай, где «будущее разума» — не метафора: добавление предиктивных слоёв (погода, лед) и смена интерполяторов — путь к более умным картам.
Хорошая история опирается на честные визуализации. Этот скрипт даёт именно такую «витрину»: карты до/после ресэмплинга и TIFF высокого разрешения для публикаций. Он не заменяет данные — он помогает их видеть. А видеть лучше — значит принимать решения, которые выдерживают столкновение с реальностью.
Скрипт начинается с очистки рабочей среды и загрузки необходимых пакетов. Задаются параметры области исследования: минимальная и максимальная долгота и широта, ограничивающие регион Баренцева моря. Загружаются данные из Excel-файла, содержащего разности температур, и преобразуются в data.frame с колонками долготы, широты и значения температуры. Создается исходный растровый объект из этих данных с указанием системы координат. Определяется целевой растр с более высоким разрешением (0.01 градуса), после чего выполняется ресэмплинг исходного растра с использованием билинейной интерполяции для сглаживания значений. Данные ресэмплинга преобразуются в data.frame с фильтрацией по заданной области и категоризацией температурных значений для построения цветовых градаций. Загружаются географические данные мировых береговых линий и создается координатная сетка. Определяется цветовая палитра для отображения температурных аномалий. Строится финальный график с использованием сглаженных данных: растровая поверхность, контуры температурных изолиний, координатная сетка и подложка мировых границ. График сохраняется в формате TIFF с высоким разрешением.
# ОЧИСТКА РАБОЧЕЙ СРЕДЫ И ЗАГРУЗКА БИБЛИОТЕК --------------------------------rm(list =ls()) # Очистка среды от предыдущих объектов# Загрузка необходимых библиотек:library(dplyr) # Для манипуляций с данными
Присоединяю пакет: 'dplyr'
Следующие объекты скрыты от 'package:stats':
filter, lag
Следующие объекты скрыты от 'package:base':
intersect, setdiff, setequal, union
library(sf) # Для работы с пространственными данными
Linking to GEOS 3.13.1, GDAL 3.10.2, PROJ 9.5.1; sf_use_s2() is TRUE
library(ggplot2) # Для построения графиковlibrary(rnaturalearth) # Для получения географических данныхlibrary(terra) # Для работы с растровыми данными
terra 1.8.42
library(metR) # Дополнительные функции для визуализации# УСТАНОВКА РАБОЧЕЙ ДИРЕКТОРИИ -----------------------------------------------setwd("C:/SUPERPIC/") # Замените на актуальный путь к вашим данным# ПАРАМЕТРЫ ОБЛАСТИ ИССЛЕДОВАНИЯ ---------------------------------------------xmin <-10# Минимальная долгота (границы Баренцева моря)xmax <-65# Максимальная долготаymin <-68# Минимальная широтаymax <-82# Максимальная широта# ПАРАМЕТРЫ РЕСЭМПЛИНГА ------------------------------------------------------new_res <-0.1# Новое разрешение в градусах после передискретизации# 1. ЗАГРУЗКА ИСХОДНЫХ ДАННЫХ -------------------------------------------------# Чтение данных из Excel-файлаNEMO <- readxl::read_excel("diffTemp.xlsx", sheet ="diffTemp")# Создание датафрейма с координатами и температурными даннымиdf <-data.frame(longitude = NEMO$Lon,latitude = NEMO$Lat,TEMP = NEMO$dif)# 2. ПОДГОТОВКА ИСХОДНЫХ ДАННЫХ ДЛЯ ВИЗУАЛИЗАЦИИ ------------------------------# Фильтрация данных по области исследования и категоризация температурDF <-as.data.frame(df, xy =TRUE, na.rm =TRUE) %>%filter( longitude >= xmin, longitude <= xmax, latitude >= ymin, latitude <= ymax ) %>%mutate(TEMP_cat =cut( TEMP,breaks =c(-Inf, 0, 0.25, 0.5, 0.75, 1, Inf),labels =c("<0", "0~0.25", "0.25~0.5", "0.5~0.75", "0.75~1", ">1"),include.lowest =TRUE ) )# 3. ЗАГРУЗКА ГЕОГРАФИЧЕСКИХ ДАННЫХ -------------------------------------------# Получение данных о береговых линиях мираworld <-ne_countries(scale =50, returnclass ="sf") %>%st_transform(4326) %>%# Преобразование в WGS84st_wrap_dateline() # Коррекция линии перемены дат# Создание координатной сеткиgraticule <-st_graticule(lat =seq(ymin, ymax, 2), # Шаг по широте: 2 градусаlon =seq(xmin, xmax, 5), # Шаг по долготе: 5 градусовdatum =st_crs(4326) # Система координат)# 4. НАСТРОЙКА ЦВЕТОВОЙ СХЕМЫ -------------------------------------------------# Цвета для отрицательных температур (холодные тона)cool_colors <-c("#2171b5", "#6baed6", "#9ecae1")# Цвета для положительных температур (теплые тона)warm_colors <-c("#fee391", "#fe9929", "#d95f0e")# Объединенная палитраpalette <-c(cool_colors, warm_colors)# 5. ПОСТРОЕНИЕ ГРАФИКА С ИСХОДНЫМ РАЗРЕШЕНИЕМ --------------------------------# Создание карты с исходными данными (низкое разрешение)plot_lowres <-ggplot() +# Отображение данных в виде растровых плитокgeom_tile(data = DF, aes(x = longitude, y = latitude, fill = TEMP_cat), alpha =0.7) +# Добавление изолиний температурgeom_contour(data = DF,aes(x = longitude, y = latitude, z = TEMP),breaks =c(0, 0.25, 0.5, 0.75, 1),color ="black",linewidth =0.2 ) +# Добавление координатной сеткиgeom_sf(data = graticule, color ="gray70", linewidth =0.3) +# Добавление береговых линийgeom_sf(data = world, color ="gray30",fill ="#E8E5D6",lwd =0.3 ) +# Настройка области отображенияcoord_sf(xlim =c(xmin, xmax),ylim =c(ymin, ymax),expand =FALSE,crs =st_crs(4326) ) +# Настройка цветовой шкалыscale_fill_manual(name ="T (°C)", # Знак дельта вместо "?"values = palette,drop =FALSE,na.value ="grey90" ) +# Настройка внешнего вида графикаtheme(panel.background =element_rect(fill ="white"),panel.border =element_rect(color ="black", fill =NA, linewidth =1.5),legend.position ="bottom",axis.title =element_blank(),text =element_text(size =12),legend.text =element_text(size =10) )# Отображение графикаplot_lowres
# 6. ПРОЦЕДУРА РЕСЭМПЛИНГА ----------------------------------------------------# Создание исходного растра из данныхr <-rast(df, type ="xyz", crs ="EPSG:4326")# Создание целевого растра с новым разрешениемtarget <-rast(extent =ext(c(xmin, xmax, ymin, ymax)),resolution = new_res,crs ="EPSG:4326")# Выполнение ресэмплинга с билинейной интерполяциейr_resampled <-resample(r, target, method ="bilinear")# 7. ПОДГОТОВКА РЕСЭМПЛИРОВАННЫХ ДАННЫХ ---------------------------------------# Преобразование растра в датафрейм для ggplot2TEMPERATURE <-as.data.frame(r_resampled, xy =TRUE, na.rm =TRUE) %>%filter( x >= xmin, x <= xmax, y >= ymin, y <= ymax ) %>%mutate(TEMP_cat =cut( TEMP,breaks =c(-Inf, 0, 0.25, 0.5, 0.75, 1, Inf),labels =c("<0", "0~0.25", "0.25~0.5", "0.5~0.75", "0.75~1", ">1"),include.lowest =TRUE ) )# 8. ПОСТРОЕНИЕ ГРАФИКА С ВЫСОКИМ РАЗРЕШЕНИЕМ ---------------------------------# Создание карты с ресэмплированными даннымиfinal_plot <-ggplot() +geom_tile(data = TEMPERATURE, aes(x = x, y = y, fill = TEMP_cat), alpha =0.7) +geom_contour(data = TEMPERATURE,aes(x = x, y = y, z = TEMP),breaks =c(0, 0.25, 0.5, 0.75, 1),color ="black",linewidth =0.2 ) +geom_sf(data = graticule, color ="gray70", linewidth =0.3) +geom_sf(data = world, color ="gray30",fill ="#E8E5D6",lwd =0.3 ) +coord_sf(xlim =c(xmin, xmax),ylim =c(ymin, ymax),expand =FALSE,crs =st_crs(4326) ) +scale_fill_manual(name ="T (°C)", # Знак дельта вместо "?"values = palette,drop =FALSE,na.value ="grey90" ) +theme(panel.background =element_rect(fill ="white"),panel.border =element_rect(color ="black", fill =NA, linewidth =1.5),legend.position ="bottom",axis.title =element_blank(),text =element_text(size =12),legend.text =element_text(size =10) )# Отображение финального графикаfinal_plot
# 9. СОХРАНЕНИЕ РЕЗУЛЬТАТОВ ---------------------------------------------------# Сохранение карты с высоким разрешением в файлggsave(filename ="Temperature_Map.tiff",plot = final_plot,device ="tiff",width =17,height =15,units ="cm",dpi =600,compression ="lzw",bg ="white")# Дополнительно: сохранение карты с исходным разрешениемggsave(filename ="Temperature_Map_LowRes.tiff",plot = plot_lowres,device ="tiff",width =17,height =15,units ="cm",dpi =600,compression ="lzw",bg ="white")