From 0066a2bce9702d84814caf36d7f6bc8a7710ce99 Mon Sep 17 00:00:00 2001 From: Firas Date: Wed, 14 Feb 2024 18:58:23 -0700 Subject: [PATCH 01/22] Fixed environment --- Project.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 9764a12..6092c5e 100644 --- a/Project.toml +++ b/Project.toml @@ -4,7 +4,9 @@ authors = ["Firas and contributors"] version = "1.0.0-DEV" [deps] -CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" +FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" [compat] julia = "1" From a59b6029bfc5afa7c9e006cbe3e9a8d71bf64ac6 Mon Sep 17 00:00:00 2001 From: Firas Date: Wed, 14 Feb 2024 19:03:35 -0700 Subject: [PATCH 02/22] Changed package structure --- src/ImageRecipe.jl | 24 -------------- src/SeisMakie.jl | 27 +++++++++++++-- src/WiggleRecipe.jl | 81 --------------------------------------------- 3 files changed, 24 insertions(+), 108 deletions(-) delete mode 100644 src/ImageRecipe.jl delete mode 100644 src/WiggleRecipe.jl diff --git a/src/ImageRecipe.jl b/src/ImageRecipe.jl deleted file mode 100644 index 06beecf..0000000 --- a/src/ImageRecipe.jl +++ /dev/null @@ -1,24 +0,0 @@ -@recipe(SeisImage, d) do scene - Attributes( - dx = 1, - dy = 1, - pclip = 98, - ) -end - -function Makie.plot!(img::SeisImage{<:Tuple{AbstractMatrix{<:Real}}}) - d = img.d - - x = (1, 100) - y = (1, 500) - - function update_plot(d) - - end - - Makie.Observables.onany(update_plot, d) - - image!(x, y, d[]') - - img -end \ No newline at end of file diff --git a/src/SeisMakie.jl b/src/SeisMakie.jl index 738dc14..4853f33 100644 --- a/src/SeisMakie.jl +++ b/src/SeisMakie.jl @@ -1,11 +1,32 @@ + module SeisMakie # Write your package code here. using Makie + using Statistics + using FFTW + + include("Recipes/SeisWiggleRecipe.jl") + include("Recipes/SeisColorRecipe.jl") + include("Recipes/SeisOverlayRecipe.jl") + + include("SeisWiggle.jl") + include("SeisOverlay.jl") + include("SeisColor.jl") + include("SeisDifference.jl") + + + include("SeisPlotFK.jl") + include("SeisPlotTX.jl") + + include("Util.jl") - include("WiggleRecipe.jl") - include("ImageRecipe.jl") + export SeisWiggle + export SeisColor + export SeisOverlay - export wiggleplot + export SeisDifference + export SeisPlotTX + export SeisPlotFK end diff --git a/src/WiggleRecipe.jl b/src/WiggleRecipe.jl deleted file mode 100644 index f0ee257..0000000 --- a/src/WiggleRecipe.jl +++ /dev/null @@ -1,81 +0,0 @@ -# @recipe(Wiggle) do scene -# Attributes( -# # vertical = false, -# ) -# end -""" - wiggle(gx, d, dt) - wiggle!(ax, gx, d, dt) - -Plots wiggle traces of seismic data. - -# Arguments: -- `gx::Vector{<:Real}`: the positions of the seismometers(?) corresponding to the traces in d -- `d::Matrix{<:AbstractFloat}`: the measured seismic traces. Number of columns corresponds to number - of traces whereas number of rows corresponds to the number of times - amplitude was measured for each trace -- `dt`::AbstractFloat: the amount of time between each measurement of amplitude -""" -@recipe(Wiggle, d) do scene - Attributes( - color = :black, - linewidth = 0.7, - - gx = "NULL", - ox = 0, - dx = 1, - - ot = 0, - dt = 1, - ) -end - -function Makie.plot!(wp::Wiggle{<:Tuple{AbstractMatrix{<:Real}}}) - - d = wp.d - gx = wp.gx - ox = wp.ox[] - dx = wp.dx[] - - ot = wp.ot[] - dt = wp.dt[] - - - if gx[] == "NULL" - gx[] = [ox+(i-1)*dx for i in range(start=1, stop=size(d[], 2))] - end - - traces = Observable(Vector{Point2f}[]) - positive_traces = Observable(Vector{Point2f}[]) - zero_lines = Observable(Vector{Point2f}[]) - ## Add colour functionality - - function update_plot(d, gx) - empty!(traces[]) - empty!(positive_traces[]) - empty!(zero_lines[]) - - dgx = minimum([gx[i]-gx[i-1] for i in 2:length(gx)]) - max_perturb = maximum(abs, d) - times = ot:dt:(dt*(size(d, 1)-1)+ot) - z = zeros(length(size(d, 1))) - for i = 1:length(gx) - trace = Point2.(gx[i] .+ (dgx/max_perturb .* d[:, i]), times) - pos_trace = Point2.(gx[i] .+ max.(dgx/max_perturb .* d[:, i], 0), times) - zero_line = Point2.(gx[i] .+ z, times) - push!(traces[], trace) - push!(positive_traces[], pos_trace) - push!(zero_lines[], zero_line) - end - end - - Makie.Observables.onany(update_plot, d, gx) - - update_plot(d[], gx[]) - - for i = 1:length(gx[]) - band!(wp, zero_lines[][i], positive_traces[][i], color=wp.color) - lines!(wp, traces[][i], color=wp.color, linewidth=wp.linewidth) - end - wp -end From db7988aa5c39f99780a116afd0f657144aaaf5e7 Mon Sep 17 00:00:00 2001 From: Firas Date: Wed, 14 Feb 2024 19:05:23 -0700 Subject: [PATCH 03/22] Completed wiggle recipe --- src/Recipes/SeisWiggleRecipe.jl | 78 +++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/Recipes/SeisWiggleRecipe.jl diff --git a/src/Recipes/SeisWiggleRecipe.jl b/src/Recipes/SeisWiggleRecipe.jl new file mode 100644 index 0000000..452b356 --- /dev/null +++ b/src/Recipes/SeisWiggleRecipe.jl @@ -0,0 +1,78 @@ +@recipe(SeisWiggleBase, d) do scene + Attributes( + wiggle_line_color = :black, + wiggle_fill_color = :black, + + trace_width = 0.7, + + gx = nothing, + ox = 0, + dx = 1, + + oy = 0, + dy = 1, + + xcur = 1.2, + wiggle_trace_increment = 1, + #wiggle_difference = 1, + + fillbands = true, + ) +end + +function Makie.plot!(wp::SeisWiggleBase{<:Tuple{AbstractMatrix{<:Real}}}) + + d = wp.d + gx = wp.gx + + ox = wp.ox[] + dx = wp.dx[] + + oy = wp.oy[] + dy = wp.dy[] + + xcur = wp.xcur[] + wiggle_trace_increment = wp.wiggle_trace_increment[] + + + if isnothing(gx[]) + gx[] = [ox+(i-1)*dx for i in range(start=1, stop=size(d[], 2))] + end + + traces = Observable(Vector{Point2f}[]) + positive_traces = Observable(Vector{Point2f}[]) + zero_lines = Observable(Vector{Point2f}[]) + + function update_plot(d, gx) + empty!(traces[]) + empty!(positive_traces[]) + empty!(zero_lines[]) + + dgx = minimum([gx[i]-gx[i-1] for i in 2:length(gx)]) + max_perturb = maximum(abs, d) + times = oy:dy:(dy*(size(d, 1)-1)+oy) + z = zeros(length(size(d, 1))) + scale = wiggle_trace_increment*dgx*xcur/max_perturb + + for i = 1:wiggle_trace_increment:length(gx) + trace = Point2.(gx[i] .+ (scale .* d[:, i]), times) + pos_trace = Point2.(gx[i] .+ max.(scale .* d[:, i], 0), times) + zero_line = Point2.(gx[i] .+ z, times) + push!(traces[], trace) + push!(positive_traces[], pos_trace) + push!(zero_lines[], zero_line) + end + end + + Makie.Observables.onany(update_plot, d, gx) + + update_plot(d[], gx[]) + + for i = 1:length(traces[]) + if wp.fillbands[] + band!(wp, zero_lines[][i], positive_traces[][i], color=wp.wiggle_fill_color) + end + lines!(wp, traces[][i], color=wp.wiggle_line_color, linewidth=wp.trace_width) + end + wp +end From 3afe92fd5ba54e5c9d20d5067414a3276ed93c00 Mon Sep 17 00:00:00 2001 From: Firas Date: Wed, 14 Feb 2024 19:06:22 -0700 Subject: [PATCH 04/22] Completed color recipe --- src/Recipes/SeisColorRecipe.jl | 47 ++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/Recipes/SeisColorRecipe.jl diff --git a/src/Recipes/SeisColorRecipe.jl b/src/Recipes/SeisColorRecipe.jl new file mode 100644 index 0000000..f8cef33 --- /dev/null +++ b/src/Recipes/SeisColorRecipe.jl @@ -0,0 +1,47 @@ +@recipe(SeisColorBase, d) do scene + Attributes( + ox = 0, + dx = 1, + oy = 0, + dy = 1, + + pclip = 98, + vmin = nothing, + vmax = nothing, + + x = nothing, + y = nothing, + + cmap = :viridis, + ) +end + +function Makie.plot!(img::SeisColorBase{<:Tuple{AbstractMatrix{<:Real}}}) + + ## Copied from SeisPlot.SeisPlotTX + if (isnothing(img.vmin[]) || isnothing(img.vmax)) + if (img.pclip[]<=100) + a = -quantile(abs.(img.d[][:]), (img.pclip[]/100)) + else + a = -quantile(abs.(img.d[][:]), 1)*img.pclip[]/100 + end + b = -a + else + a = img.vmin[] + b = img.vmax[] + end + + if isnothing(img.y[]) + img.y[] = (img.oy[], img.oy[]+size(img.d[],1)*img.dy[]) + end + + if isnothing(img.x[]) + img.x[] = (img.ox[]-img.dx[], img.ox[]+size(img.d[],2)*img.dx[]) + end + + image!(img, img.x[], img.y[], img.d[]', colorrange=(a, b), colormap=img.cmap[]) + # d = img.d[][x[1]:x[2], y[1]:y[2]] + # image!(img, y, x, d', colorrange=(a, b), colormap=img.colormap[]) + + img +end \ No newline at end of file From c06c64ff7d3f2908125b19f44c5029779d909d98 Mon Sep 17 00:00:00 2001 From: Firas Date: Wed, 14 Feb 2024 19:06:51 -0700 Subject: [PATCH 05/22] Completed overlay recipe --- src/Recipes/SeisOverlayRecipe.jl | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/Recipes/SeisOverlayRecipe.jl diff --git a/src/Recipes/SeisOverlayRecipe.jl b/src/Recipes/SeisOverlayRecipe.jl new file mode 100644 index 0000000..aaaf571 --- /dev/null +++ b/src/Recipes/SeisOverlayRecipe.jl @@ -0,0 +1,48 @@ +@recipe(SeisOverlayBase, d) do scene + Attributes( + trace_color = :black, + trace_width = 0.7, + + gx = nothing, + ox = 0, + dx = 1, + + oy = 0, + dy = 1, + + xcur = 1, + wiggle_trace_increment = 1, + + pclip = 98, + vmin = nothing, + vmax = nothing, + + x = (1, 500), + y = (1, 100), + + cmap = :viridis + ) +end + +function Makie.plot!(overlay::SeisOverlayBase{<:Tuple{AbstractMatrix{<:Real}}}) + + if !isnothing(overlay.gx[]) + overlay.ox[] = overlay.gx[][1] + overlay.dx[] = (overlay.gx[][end] - overlay.gx[][1]) / length(overlay.gx[]) + end + + seiscolorbase!(overlay, overlay.d[], ox=overlay.ox[], dx=overlay.dx[], oy=overlay.oy[], dy=overlay.dy[], colormap=overlay.cmap[], + vmin=overlay.vmin[], vmax=overlay.vmax[], pclip=overlay.pclip[]) + seiswigglebase!(overlay, overlay.d[], gx=overlay.gx[], ox=overlay.ox[], dx=overlay.dx[], oy=overlay.oy[], dy=overlay.dy[], + xcur=overlay.xcur[], wiggle_trace_increment=overlay.wiggle_trace_increment[], trace_color=overlay.trace_color[], + trace_width=overlay.trace_width[], fillbands=false) + + overlay +end + +function Makie.extract_colormap(pl::Plot{seisoverlaybase, Tuple{Matrix{Float64}}}) + # Return the ColorMapping of the SeisColor plot + # - typeof(pl.plots[1] is seiscolorbase) = Plot{SeisMakie.seiscolorbase, Tuple{Matrix{Float64}}} + # - typeof(pl.plots[1].plots[1]) = Image{Tuple{ClosedInterval{Float32}, ClosedInterval{Float32}, Matrix{Float32}}} + return Makie.extract_colormap(pl.plots[1].plots[1]) +end \ No newline at end of file From 77b5fa3a9fedaa017911c9444654b9f853f9dc1e Mon Sep 17 00:00:00 2001 From: Firas Date: Wed, 14 Feb 2024 19:11:42 -0700 Subject: [PATCH 06/22] Added utility function used to create Axis objects with required attributes --- src/Util.jl | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/Util.jl diff --git a/src/Util.jl b/src/Util.jl new file mode 100644 index 0000000..c157164 --- /dev/null +++ b/src/Util.jl @@ -0,0 +1,6 @@ +""" + Creates an Axis object to be used by SeisColor, SeisOverlay, SeisWiggle. +""" +function __create_axis(fig) + return Axis(fig, yreversed=true, xautolimitmargin=(0,0), yautolimitmargin=(0,0)) +end \ No newline at end of file From d5bd732c32f8beb1a288500022ad66f609b557a4 Mon Sep 17 00:00:00 2001 From: Firas Date: Wed, 14 Feb 2024 19:07:47 -0700 Subject: [PATCH 07/22] Completed wrappers that create and return an axis --- src/SeisColor.jl | 44 +++++++++++++++++++++++++++++++++++++ src/SeisOverlay.jl | 55 ++++++++++++++++++++++++++++++++++++++++++++++ src/SeisWiggle.jl | 53 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 src/SeisColor.jl create mode 100644 src/SeisOverlay.jl create mode 100644 src/SeisWiggle.jl diff --git a/src/SeisColor.jl b/src/SeisColor.jl new file mode 100644 index 0000000..732ca64 --- /dev/null +++ b/src/SeisColor.jl @@ -0,0 +1,44 @@ +""" + SeisColor(d; ) + +Plot time-space, color plot of 2D seismic data `d`. + +# Arguments: +- `d::Matrix{<:AbstractFloat}`: 2D seismic data to be plotted. + +# Keyword Arguments: +- `fig::Figure=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. + +- `ox=0`: first point of x-axis. +- `dx=1`: increment of x-axis. +- `oy=0`: first point of y-axis. +- `dy=1`: increment of y-axis. + +- `pclip=98`: percentile for determining clip. +- `vmin=nothing`: minimum value used in colormapping data. +- `vmax=nothing`: maximum value used in colormapping data. + +- `cmap=:viridis`: the colormap to be used. + +Return the figure and axis corresponding to d. + +# Example +```julia +julia> d = SeisLinearEvents(); SeisColor(d); +``` +""" +function SeisColor(d; + fig=nothing, ox=0, dx=1, oy=0, dy=1, + pclip=98, vmin=nothing, vmax=nothing, cmap=:viridis, kwargs...) + + if isnothing(fig) + fig = Figure() + end + + ax = __create_axis(fig[1,1]) + xlims!(ax, low=ox-dx, high=ox+size(d,2)*dx) + img = seiscolorbase!(ax, d, ox=ox, dx=dx, oy=oy, dy=dy, pclip=pclip, vmin=vmin, vmax=vmax, cmap=cmap) + Colorbar(fig[1,2], img) + + return fig, ax +end \ No newline at end of file diff --git a/src/SeisOverlay.jl b/src/SeisOverlay.jl new file mode 100644 index 0000000..3f7ad86 --- /dev/null +++ b/src/SeisOverlay.jl @@ -0,0 +1,55 @@ +""" + SeisOverlay(d; ) + +Plot time-space, overlay plot of 2D seismic data `d`. + +# Arguments: +- `d::Matrix{<:AbstractFloat}`: 2D seismic data to be plotted. + +# Keyword Arguments: +- `fig::Figure=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. + +- `gx::Vector{<:Real}=nothing`: the real coordinates of the seismometers corresponding to the traces in d +- `ox=0`: first point of x-axis. +- `dx=1`: increment of x-axis. +- `oy=0`: first point of y-axis. +- `dy=1`: increment of y-axis. + +- `pclip=98`: percentile for determining clip. +- `vmin=nothing`: minimum value used in colormapping data. +- `vmax=nothing`: maximum value used in colormapping data. + +- `wiggle_fill_color=:black`: color for filling the positive wiggles. +- `wiggle_line_color=:black`: color for wiggles' lines. +- `wiggle_trace_increment=1`: increment for wiggle traces. +- `xcur=1.2`: wiggle excursion in traces corresponding to clip. + +- `cmap=:viridis`: the colormap to be used. + +Return the figure and axis corresponding to d. + +# Example +```julia +julia> d = SeisLinearEvents(); SeisOverlay(d); +``` +""" +function SeisOverlay(d; + fig=nothing, ox=0, dx=1, oy=0, dy=1, gx=nothing, xcur=1.2, wiggle_trace_increment=1, + pclip=98, vmin=nothing, vmax=nothing, + wiggle_line_color=:black, wiggle_fill_color=:black,trace_width=0.7, + cmap=:viridis, kwargs...) + + if isnothing(fig) + fig = Figure() + end + + ax = __create_axis(fig[1, 1]) + xlims!(ax, low=ox-dx, high=ox+size(d,2)*dx) + overlay = seisoverlaybase!(ax, d, ox=ox, dx=dx, oy=oy, dy=dy, gx=gx, pclip=pclip, vmin=vmin, vmax=vmax, xcur=xcur, + wiggle_trace_increment=wiggle_trace_increment, wiggle_line_color=wiggle_line_color, + wiggle_fill_color=wiggle_fill_color, trace_width=trace_width, cmap=cmap) + + Colorbar(fig[1, 2], overlay) + + return fig, ax +end \ No newline at end of file diff --git a/src/SeisWiggle.jl b/src/SeisWiggle.jl new file mode 100644 index 0000000..fe973ab --- /dev/null +++ b/src/SeisWiggle.jl @@ -0,0 +1,53 @@ +""" + SeisWiggle(d; ) + +Plot time-space, wiggle plot of 2D seismic data `d`. + +# Arguments: +- `d::Matrix{<:AbstractFloat}`: the measured seismic traces. Number of columns corresponds to number + of traces whereas number of rows corresponds to the number of times + amplitude was measured for each trace + +# Keyword Arguments: +- `fig::Figure=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. + +- `gx::Vector{<:Real}=nothing`: the real coordinates of the seismometers corresponding to the traces in d +- `ox=0`: first point of x-axis. +- `dx=1`: increment of x-axis. +- `oy=0`: first point of y-axis. +- `dy=1`: increment of y-axis. + +- `wiggle_fill_color=:black`: color for filling the positive wiggles. +- `wiggle_line_color=:black`: color for wiggles' lines. +- `wiggle_trace_increment=1`: increment for wiggle traces. +- `xcur=1.2`: wiggle excursion in traces. + +Return the figure and axis corresponding to d. + +# Example +```julia +julia> d = SeisLinearEvents(); SeisWiggle(d); +``` +""" +function SeisWiggle(d; + fig=nothing, gx=nothing, ox=0, dx=1, oy=0, dy=1, + xcur=1.2, wiggle_trace_increment=1, trace_width=0.7, + wiggle_line_color=:black, wiggle_fill_color=:black, + kwargs...) + + if isnothing(fig) + fig = Figure() + end + + ax = __create_axis(fig[1,1]) + if !isnothing(gx) + ox = gx[1] + dx = minimum([gx[i]-gx[i-1] for i = 2:length(gx)]) + end + xlims!(ax, low=ox-dx, high=ox+size(d,2)*dx) + seiswigglebase!(ax, d, gx=gx, ox=ox, dx=dx, oy=oy, dy=dy, xcur=xcur, wiggle_trace_increment=wiggle_trace_increment, + wiggle_line_color=wiggle_line_color, wiggle_fill_color=wiggle_fill_color, + trace_width=trace_width) + + return fig, ax +end \ No newline at end of file From 5c8e5f044771ad166d1678fe7d5a4ffaa7c6c73a Mon Sep 17 00:00:00 2001 From: Firas Date: Wed, 14 Feb 2024 19:08:44 -0700 Subject: [PATCH 08/22] Added a function that allows specifying a 'style' parameter to use SeisWiggle, SeisColor, SeisOverlay --- src/SeisPlotTX.jl | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/SeisPlotTX.jl diff --git a/src/SeisPlotTX.jl b/src/SeisPlotTX.jl new file mode 100644 index 0000000..05a4900 --- /dev/null +++ b/src/SeisPlotTX.jl @@ -0,0 +1,51 @@ +""" + SeisPlotTX(d; ) + +Plot time-space, 2D seismic data `d` with color, wiggles or overlay. + +# Arguments: +- `d::Matrix{<:AbstractFloat}`: the measured seismic traces. Number of columns corresponds to number + of traces whereas number of rows corresponds to the number of times + amplitude was measured for each trace + +# Keyword Arguments: +- `fig::Figure=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. + +- `gx::Vector{<:Real}=nothing`: the real coordinates of the seismometers corresponding to the traces in d +- `ox=0`: first point of x-axis. +- `dx=1`: increment of x-axis. +- `oy=0`: first point of y-axis. +- `dy=1`: increment of y-axis. + +- `pclip=98`: percentile for determining clip. +- `vmin=nothing`: minimum value used in colormapping data. +- `vmax=nothing`: maximum value used in colormapping data. + +- `wiggle_fill_color=:black`: color for filling the positive wiggles. +- `wiggle_line_color=:black`: color for wiggles' lines. +- `wiggle_trace_increment=1`: increment for wiggle traces. +- `xcur=1.2`: wiggle excursion in traces corresponding to clip. + +- `colormap=:viridis`: the colormap to be used for color and overlay plots. + +- `style`: determines the type of plot. Can be either "wiggle"/"wiggles", "color", "overlay". + +Return the figure and axis corresponding to d. + +# Example +```julia +julia> d = SeisLinearEvents(); SeisPlotTX(d); +``` +""" +function SeisPlotTX(d; style="color", kwargs...) + + if style == "overlay" + return SeisOverlay(d; kwargs...) + elseif style == "wiggles" || style == "wiggle" + return SeisWiggle(d; kwargs...) + else + return SeisColor(d; kwargs...) + end + +end + From 391a8cd5d4f7169e9a520e6f71a5d35aa7f44877 Mon Sep 17 00:00:00 2001 From: Firas Date: Wed, 14 Feb 2024 19:09:31 -0700 Subject: [PATCH 09/22] Created a function that takes in 2 matrices, plots them and their difference, and returns the 3 axes --- src/SeisDifference.jl | 76 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/SeisDifference.jl diff --git a/src/SeisDifference.jl b/src/SeisDifference.jl new file mode 100644 index 0000000..ba6a1ed --- /dev/null +++ b/src/SeisDifference.jl @@ -0,0 +1,76 @@ +""" + SeisDifference(d1, d2; ) + +Plot time-space, 2D seismic data `d1`, `d2`, and their difference (`d1 - d2`) with color, wiggles or overlay. + +# Arguments: +- `d1::Matrix{<:AbstractFloat}`: the measured seismic traces. Number of columns corresponds to number + of traces whereas number of rows corresponds to the number of times + amplitude was measured for each trace +- `d2::Matrix{<:AbstractFloat}`: same description as d1. + +# Keyword Arguments: +- `fig::Figure=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. + +- `gx::Vector{<:Real}=nothing`: the real coordinates of the seismometers corresponding to the traces in d +- `ox=0`: first point of x-axis. +- `dx=1`: increment of x-axis. +- `oy=0`: first point of y-axis. +- `dy=1`: increment of y-axis. + +- `pclip=98`: percentile for determining clip. +- `vmin=nothing`: minimum value used in colormapping data. +- `vmax=nothing`: maximum value used in colormapping data. + +- `wiggle_fill_color=:black`: color for filling the positive wiggles. +- `wiggle_line_color=:black`: color for wiggles' lines. +- `wiggle_trace_increment=1`: increment for wiggle traces. +- `xcur=1.2`: wiggle excursion in traces corresponding to clip. + +- `cmap=:viridis`: the colormap to be used for color and overlay plots. + +- `style`: determines the type of plot. Can be either "wiggle"/"wiggles", "color", "overlay". + +Return the figure and 3 axes corresponding to d1, d2, d1-d2. + +# Example +```julia +julia> d1 = SeisLinearEvents(); d2 = SeisLinearEvents(); SeisDifference(d1, d2); +``` +""" +function SeisDifference(d1, d2; + fig=nothing, ox=0, dx=1, oy=0, dy=1, gx=nothing, + pclip=98, vmin=nothing, vmax=nothing, wiggle_line_color=:black, + wiggle_fill_color=:black, trace_width=0.7, cmap=:viridis, style="overlay") + + if isnothing(fig) + fig = Figure() + end + + if style == "overlay" + plotfunc = seisoverlaybase! + elseif style == "wiggles" || style == "wiggle" + plotfunc = seiswigglebase! + else + plotfunc = seiscolorbase! + end + + axes = [__create_axis(fig[1, 1], ), __create_axis(fig[2, 1]), __create_axis(fig[1, 3])] + data = [d1, d2, d1 .- d2] + plots = [] + + for (i, ax) in enumerate(axes) + xlims!(ax, low=ox-dx, high=ox+size(d,2)*dx) + push!(plots, plotfunc(ax, data[i], ox=ox, dx=dx, oy=oy, dy=dy, gx=gx, pclip=pclip, vmin=vmin, vmax=vmax, + wiggle_line_color=wiggle_line_color, wiggle_fill_color=wiggle_fill_color, + trace_width=trace_width, cmap=cmap)) + end + + if !(style == "wiggles" || style == "wiggle") + Colorbar(fig[1, 2], plots[1]) + Colorbar(fig[2, 2], plots[2]) + Colorbar(fig[1, 4], plots[3]) + end + + return fig, axes[1], axes[2], axes[3] +end \ No newline at end of file From ae5ff6857d36871d1f21ef26568cb726c429acec Mon Sep 17 00:00:00 2001 From: Firas Date: Wed, 14 Feb 2024 19:12:05 -0700 Subject: [PATCH 10/22] Added SeisPlotFK functionality --- src/SeisPlotFK.jl | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/SeisPlotFK.jl diff --git a/src/SeisPlotFK.jl b/src/SeisPlotFK.jl new file mode 100644 index 0000000..1d625bf --- /dev/null +++ b/src/SeisPlotFK.jl @@ -0,0 +1,78 @@ +""" + SeisPlotFK(d; ) + +Plot time-space, frequency-wavenumber or amplitude-frequency 2D seismic data `d` +with color, wiggles or overlay. + +# Arguments +- `d::Matrix{<:AbstractFloat}`: 2D data to plot. + +# Keyword arguments: +- `fig::Figure=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. + +- `pclip=99.9`: percentile for determining clip. +- `vmin=nothing`: minimum value used in colormapping data. +- `vmax=nothing`: maximum value used in colormapping data. + +- `fmax=100`: maximum frequency for `"FK"` or `"Amplitude"` plot. + +- `ox=0`: first point of x-axis. +- `dx=1`: increment of x-axis. +- `oy=0`: first point of y-axis. +- `dy=1`: increment of y-axis. + +- `cmap=:PuOr`: colormap for `"color"` or `"overlay"` style. + +Return the figure and axis corresponding to d. + +# Example +```julia +julia> d = SeisLinearEvents(); SeisPlotFK(d); +``` +""" +function SeisPlotFK(d; fig=nothing, ox=0, dx=1, oy=0, dy=1, fmax=100, + pclip=99.9, vmin=nothing, vmax=nothing, cmap=:PuOr) + + if isnothing(fig) + fig = Figure() + end + + ax = __create_axis(fig[1, 1]) + + dk = 1/dx/size(d, 2) + kmin = -dk*size(d, 2)/2 + kmax = dk*size(d, 2)/2 + + df = 1/dy/size(d, 1) + FMAX = df*size(d, 1)/2 + if fmax > FMAX + fmax = FMAX + end + nf = convert(Int32, floor((size(d, 1)/2)*fmax/FMAX)) + D = abs.(fftshift(fft(d))) + D = D[round(Int,end/2):round(Int,end/2)+nf, :] + if (isnothing(vmin) || isnothing(vmax)) + a = 0. + if (pclip<=100) + b = quantile(abs.(D[:]), (pclip/100)) + else + b = quantile(abs.(D[:]), 1)*pclip/100 + end + else + a = vmin + b = vmax + end + + image!(ax, (kmin, kmax), (0.0, 0.5), D', colorrange=(a, b), colormap=:PuOr) + + ax.xlabel = "Wavenumber (1/m)" + ax.ylabel = "Frequency (Hz)" + + ax.xlabelsize = 14 + ax.ylabelsize = 14 + + ax.xticklabelsize = 11 + ax.yticklabelsize = 11 + + return fig, ax +end \ No newline at end of file From 89f53790f07c7a9835b79e49638169258da81bca Mon Sep 17 00:00:00 2001 From: Firas Date: Wed, 14 Feb 2024 19:15:09 -0700 Subject: [PATCH 11/22] Modified .gitignore to ignore all Manifest.toml files --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5a16984..015cd1c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -/Manifest.toml +*Manifest.toml /docs/Manifest.toml /docs/build/ From f0d3d21f27f1efb250d34bf078fb43a0a57a8eb9 Mon Sep 17 00:00:00 2001 From: Firas Date: Wed, 14 Feb 2024 19:16:33 -0700 Subject: [PATCH 12/22] Added examples in a Pluto Notebook --- examples/Project.toml | 5 + examples/tutorialSeisMakie.jl | 299 ++++++++++++++++++++++++++++++++++ 2 files changed, 304 insertions(+) create mode 100644 examples/Project.toml create mode 100644 examples/tutorialSeisMakie.jl diff --git a/examples/Project.toml b/examples/Project.toml new file mode 100644 index 0000000..4f7ee01 --- /dev/null +++ b/examples/Project.toml @@ -0,0 +1,5 @@ +[deps] +CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" +PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +SeisMakie = "1618359f-28d0-421c-9c3d-0705aaf8cc0d" +SeisProcessing = "3ac90d68-5a11-50c7-932e-af3f40d97fdc" diff --git a/examples/tutorialSeisMakie.jl b/examples/tutorialSeisMakie.jl new file mode 100644 index 0000000..6d7c2f0 --- /dev/null +++ b/examples/tutorialSeisMakie.jl @@ -0,0 +1,299 @@ +### A Pluto.jl notebook ### +# v0.19.37 + +using Markdown +using InteractiveUtils + +# ╔═╡ 93296b66-bca6-11ee-0787-99798c15a928 +begin + using Pkg + Pkg.activate(".") + Pkg.precompile() + Pkg.resolve() + using CairoMakie + using SeisMakie + + using SeisProcessing + using Random +end + +# ╔═╡ 90077fbb-2384-4d12-b51a-f52758049e49 +md""" +# SeisMakie Showcase +""" + +# ╔═╡ 62e31cae-8deb-49a5-a6a1-54a772b48ff6 +md""" +## Initializing Data +""" + +# ╔═╡ e12751b3-0c8d-4655-b606-ae94d670b0d0 +begin + D1= SeisParabEvents() + D2= SeisLinearEvents() + + D = SeisAddNoise( D1 + 0.1*D2,2) + nothing +end + +# ╔═╡ 26992493-fe50-4f59-8141-9ea9e8606516 + + +# ╔═╡ abe64b2a-f192-4e3b-ba3e-f26286b1a38d +md""" +## SeisWiggle +""" + +# ╔═╡ c25286cd-82b5-4725-96cc-4ab6ed0aa121 +begin + f1, ax1 = SeisWiggle(D) + f1 +end + +# ╔═╡ 25c72bf7-28ce-4f6b-b4c4-24be2f51a5f9 +begin + function start_and_interval() + ox, dx = 1000, 3 + oy, dy = 500, 5 + f, ax = SeisWiggle(D, ox=ox, dx=dx, oy=oy, dy=dy) + f + end + start_and_interval() +end + +# ╔═╡ 13980acc-8aa1-4d87-ab7e-c1a599e0483d +begin + function real_coords() + d = SeisLinearEvents() + dx = 10 + dt = 0.004 + gx = [ dx*(i-1) for i=1:size(d,2) ] + # create a random permutation vector to sample gx and dependent + p = (randsubseq(gx, 0.85) .÷ dx) .+ 1 + gx = gx[p] + d = d[:, p] + + f, ax = SeisWiggle(d, gx=gx) + f + end + real_coords() +end + +# ╔═╡ 38fcc0c0-aaaa-4777-b67c-9cc5c9289a91 +begin + function excursion() + f, ax = SeisWiggle(D, xcur=5) + f + end + excursion() +end + +# ╔═╡ 9a61b3d7-3a77-417d-b60b-7172050167e4 +begin + function trace_increment() + f, ax = SeisWiggle(D, wiggle_trace_increment=4) + f + end + trace_increment() +end + +# ╔═╡ e6f38a8d-3db9-47ed-801e-2f434d2ef70c +begin + function formatting() + f, ax = SeisWiggle(D, wiggle_trace_increment=4, wiggle_line_color=:orange, wiggle_fill_color=:purple) + f + end + formatting() +end + +# ╔═╡ a66db96a-a6f1-4628-8a89-d8b2744eb3b5 +md""" +## SeisColor +""" + +# ╔═╡ 0a63424d-ab08-4dd4-bff8-5239ec312733 +begin + function base_color() + f, ax = SeisColor(D) + f + end + base_color() +end + +# ╔═╡ a546c9bc-7d20-4636-850f-f900194e97e8 +begin + function with_pclip() + f, ax = SeisColor(D, pclip=95) + f + end + dx = 1 + with_pclip() +end + +# ╔═╡ 9aff572e-683c-4085-878f-8c87c046db6f +begin + function with_vmin_vmax() + f, ax = SeisColor(D, vmin=-0.1, vmax=0.4) + f + end + with_vmin_vmax() +end + +# ╔═╡ 21cb4890-628a-4331-a163-77fd8b3c9e05 +begin + function with_different_colormap() + f, ax = SeisColor(D, colormap=:seismic) + f + end + with_different_colormap() +end + +# ╔═╡ 526287c9-8d28-4357-8313-6f7ba2f2f49b +md""" +## SeisOverlay +You can use a combination of the arguments supplied to SeisWiggle and SeisColor +""" + +# ╔═╡ 312a0197-d66c-436d-9452-7c70e4cfaded +begin + function base_overlay() + f, ax = SeisOverlay(D) + f + end + base_overlay() +end + +# ╔═╡ 483422b0-666b-4600-a96b-9dd84ca19298 +begin + function overlay_with_args() + f, ax = SeisOverlay(D, ox=20, dx=10, oy=500, dy=3, colormap=:seismic, vmin=-0.2, vmax=0.3) + f + end + overlay_with_args() +end + +# ╔═╡ 2b231e00-8952-4bfc-b26e-79abcc6258e9 +md""" +## SeisPlotTX +Based on request. Pass in the arguments you want along with a `style` keyword. `style` can be one of "wiggle", "overlay", "color". +""" + +# ╔═╡ 6ccaf31a-caa8-4118-861d-9dd960b28d73 +begin + function seisplottx_demo() + f, ax = SeisPlotTX(D, style="overlay") + f + end + seisplottx_demo() +end + +# ╔═╡ ee40ceea-7d3f-4578-902d-d1518f4c7c84 +md""" +## SeisPlotFK +""" + +# ╔═╡ e12d35e5-4ea6-42f4-a396-92e4d4ebc5c7 +begin + function seisplotfk_demo() + f, ax = SeisPlotFK(D) + f + end + seisplotfk_demo() +end + +# ╔═╡ 3947a6c1-4bbe-4ee0-a3e6-114e481dc49c +md""" +## Modifying Axis Attributes +You can edit axes as shown below. For more info, go to: https://docs.makie.org/stable/reference/blocks/axis/ +""" + +# ╔═╡ c0246b4f-134b-4413-9cae-f8dd1d4986b7 +begin + function modifying_axis() + # All the functions mentioned above return an axis that can be edited + f, ax = SeisOverlay(D, pclip=97) + ax.title = "Overlay Plot (SeisMakie)" + ax.xlabel = "Trace Number" + ax.ylabel = "Time (s)" + ax.xticks = [0, 50, 99] + f + end + modifying_axis() +end + +# ╔═╡ b0f62fbd-a577-45a0-be31-aab76babb417 +md""" +## Plotting on an Existing Figure +""" + +# ╔═╡ cf728878-fefb-4d46-a52e-1d0820248d35 +begin + function multiple_plots() + # You can initialize a figure first, or use the figure returned + # by the first function. The position of the axis on the figure is indexed as + # shown below + f = Figure() + _, wiggle_ax = SeisWiggle(D, fig=f[1,1], wiggle_trace_increment=4) + _, color_ax = SeisColor(D, fig=f[2, 1]) + _, overlay_ax = SeisOverlay(D, fig=f[1,2], wiggle_trace_increment=4) + + wiggle_ax.title = "Wiggle" + color_ax.title = "Color" + overlay_ax.title = "Overlay" + f + end + multiple_plots() +end + +# ╔═╡ 01db2622-4b44-492d-a0f6-838018727e75 +md""" +## Saving a figure +""" + +# ╔═╡ 8dcce330-fad7-4dde-86c9-f3c732089278 +begin + function save_fig() + f, ax = SeisOverlay(D) + save("overlay_plot.png", f) + end +end + +# ╔═╡ f2ac7e44-7a07-4956-9f22-526af10d1fe0 + + +# ╔═╡ 1fcb8085-02f2-4907-999a-19db73ce4563 + + +# ╔═╡ Cell order: +# ╠═93296b66-bca6-11ee-0787-99798c15a928 +# ╠═90077fbb-2384-4d12-b51a-f52758049e49 +# ╠═62e31cae-8deb-49a5-a6a1-54a772b48ff6 +# ╠═e12751b3-0c8d-4655-b606-ae94d670b0d0 +# ╠═26992493-fe50-4f59-8141-9ea9e8606516 +# ╠═abe64b2a-f192-4e3b-ba3e-f26286b1a38d +# ╠═c25286cd-82b5-4725-96cc-4ab6ed0aa121 +# ╠═25c72bf7-28ce-4f6b-b4c4-24be2f51a5f9 +# ╠═13980acc-8aa1-4d87-ab7e-c1a599e0483d +# ╠═38fcc0c0-aaaa-4777-b67c-9cc5c9289a91 +# ╠═9a61b3d7-3a77-417d-b60b-7172050167e4 +# ╠═e6f38a8d-3db9-47ed-801e-2f434d2ef70c +# ╠═a66db96a-a6f1-4628-8a89-d8b2744eb3b5 +# ╠═0a63424d-ab08-4dd4-bff8-5239ec312733 +# ╠═a546c9bc-7d20-4636-850f-f900194e97e8 +# ╠═9aff572e-683c-4085-878f-8c87c046db6f +# ╠═21cb4890-628a-4331-a163-77fd8b3c9e05 +# ╠═526287c9-8d28-4357-8313-6f7ba2f2f49b +# ╠═312a0197-d66c-436d-9452-7c70e4cfaded +# ╠═483422b0-666b-4600-a96b-9dd84ca19298 +# ╠═2b231e00-8952-4bfc-b26e-79abcc6258e9 +# ╠═6ccaf31a-caa8-4118-861d-9dd960b28d73 +# ╠═ee40ceea-7d3f-4578-902d-d1518f4c7c84 +# ╠═e12d35e5-4ea6-42f4-a396-92e4d4ebc5c7 +# ╠═3947a6c1-4bbe-4ee0-a3e6-114e481dc49c +# ╠═c0246b4f-134b-4413-9cae-f8dd1d4986b7 +# ╠═b0f62fbd-a577-45a0-be31-aab76babb417 +# ╠═cf728878-fefb-4d46-a52e-1d0820248d35 +# ╠═01db2622-4b44-492d-a0f6-838018727e75 +# ╠═8dcce330-fad7-4dde-86c9-f3c732089278 +# ╠═f2ac7e44-7a07-4956-9f22-526af10d1fe0 +# ╠═1fcb8085-02f2-4907-999a-19db73ce4563 From 24fd3d6d38969ae3e7c8e1c2bd9d3fd1f745154f Mon Sep 17 00:00:00 2001 From: Firas Date: Thu, 15 Feb 2024 16:24:13 -0700 Subject: [PATCH 13/22] Removed unused package from runtests.jl --- test/runtests.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 6068a1c..160be3f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,5 @@ using SeisMakie using Test -using SeisProcessing @testset "SeisMakie.jl" begin # Write your tests here From 40e48b1e30641a46041dbcef3d22c8d191151596 Mon Sep 17 00:00:00 2001 From: Firas Date: Tue, 20 Feb 2024 02:31:52 -0700 Subject: [PATCH 14/22] Renamed color plots to image plots --- src/Recipes/SeisColorRecipe.jl | 47 ---------------------------------- 1 file changed, 47 deletions(-) delete mode 100644 src/Recipes/SeisColorRecipe.jl diff --git a/src/Recipes/SeisColorRecipe.jl b/src/Recipes/SeisColorRecipe.jl deleted file mode 100644 index f8cef33..0000000 --- a/src/Recipes/SeisColorRecipe.jl +++ /dev/null @@ -1,47 +0,0 @@ -@recipe(SeisColorBase, d) do scene - Attributes( - ox = 0, - dx = 1, - oy = 0, - dy = 1, - - pclip = 98, - vmin = nothing, - vmax = nothing, - - x = nothing, - y = nothing, - - cmap = :viridis, - ) -end - -function Makie.plot!(img::SeisColorBase{<:Tuple{AbstractMatrix{<:Real}}}) - - ## Copied from SeisPlot.SeisPlotTX - if (isnothing(img.vmin[]) || isnothing(img.vmax)) - if (img.pclip[]<=100) - a = -quantile(abs.(img.d[][:]), (img.pclip[]/100)) - else - a = -quantile(abs.(img.d[][:]), 1)*img.pclip[]/100 - end - b = -a - else - a = img.vmin[] - b = img.vmax[] - end - - if isnothing(img.y[]) - img.y[] = (img.oy[], img.oy[]+size(img.d[],1)*img.dy[]) - end - - if isnothing(img.x[]) - img.x[] = (img.ox[]-img.dx[], img.ox[]+size(img.d[],2)*img.dx[]) - end - - image!(img, img.x[], img.y[], img.d[]', colorrange=(a, b), colormap=img.cmap[]) - # d = img.d[][x[1]:x[2], y[1]:y[2]] - # image!(img, y, x, d', colorrange=(a, b), colormap=img.colormap[]) - - img -end \ No newline at end of file From effcf9ceff199efcb19c8467a7ff032f032573ee Mon Sep 17 00:00:00 2001 From: Firas Date: Tue, 20 Feb 2024 02:30:06 -0700 Subject: [PATCH 15/22] Removed 'base' from overlay, wiggle, and image recipes --- src/Recipes/SeisImageRecipe.jl | 67 ++++++++++++++++++++++++++++++++ src/Recipes/SeisOverlayRecipe.jl | 58 ++++++++++++++++++++------- src/Recipes/SeisWiggleRecipe.jl | 39 +++++++++++++++++-- 3 files changed, 147 insertions(+), 17 deletions(-) create mode 100644 src/Recipes/SeisImageRecipe.jl diff --git a/src/Recipes/SeisImageRecipe.jl b/src/Recipes/SeisImageRecipe.jl new file mode 100644 index 0000000..819ef2d --- /dev/null +++ b/src/Recipes/SeisImageRecipe.jl @@ -0,0 +1,67 @@ +""" + seisimage(d; ); + seisimage!(ax, d; ); + +Recipe to plot time-space, color plot of 2D seismic data `d`. + +# Arguments: +- `d::Matrix{<:AbstractFloat}`: 2D seismic data to be plotted. + +# Keyword Arguments: +- `ox=0`: first point of x-axis. +- `dx=1`: increment of x-axis. +- `oy=0`: first point of y-axis. +- `dy=1`: increment of y-axis. + +- `pclip=98`: percentile for determining clip. +- `vmin=nothing`: minimum value used in colormapping data. +- `vmax=nothing`: maximum value used in colormapping data. + +- `cmap=:seismic`: the colormap to be used. + +# Examples +```julia +julia> d = SeisLinearEvents(); +julia> f, ax, img = seisimage(d) +``` +```julia +julia> d = SeisLinearEvents(); f = Figure(); ax = Axis(f) +julia> img = seisimage!(ax, d) +``` +""" +@recipe(SeisImage, d) do scene + Attributes( + ox = 0, + dx = 1, + oy = 0, + dy = 1, + + pclip = 98, + vmin = nothing, + vmax = nothing, + + cmap = :seismic, + ) +end + +function Makie.plot!(img::SeisImage{<:Tuple{AbstractMatrix{<:Real}}}) + + if (isnothing(img.vmin[]) || isnothing(img.vmax)) + if (img.pclip[]<=100) + a = -quantile(abs.(img.d[][:]), (img.pclip[]/100)) + else + a = -quantile(abs.(img.d[][:]), 1)*img.pclip[]/100 + end + b = -a + else + a = img.vmin[] + b = img.vmax[] + end + + x = (img.ox[]-img.dx[], img.ox[]+size(img.d[],2)*img.dx[]) + y = (img.oy[], img.oy[]+size(img.d[],1)*img.dy[]) + + image!(img, x, y, img.d[]', colorrange=(a, b), colormap=img.cmap[]) + + img +end \ No newline at end of file diff --git a/src/Recipes/SeisOverlayRecipe.jl b/src/Recipes/SeisOverlayRecipe.jl index aaaf571..c3e2f6f 100644 --- a/src/Recipes/SeisOverlayRecipe.jl +++ b/src/Recipes/SeisOverlayRecipe.jl @@ -1,9 +1,44 @@ -@recipe(SeisOverlayBase, d) do scene +""" + seisoverlay(d; ) + seisoverlay!(ax, d; ) + +Recipe to plot time-space, overlay plot of 2D seismic data `d`. + +# Arguments: +- `d::Matrix{<:AbstractFloat}`: 2D seismic data to be plotted. + +# Keyword Arguments: +- `ox=0`: first point of x-axis. +- `dx=1`: increment of x-axis. +- `oy=0`: first point of y-axis. +- `dy=1`: increment of y-axis. + +- `pclip=98`: percentile for determining clip. +- `vmin=nothing`: minimum value used in colormapping data. +- `vmax=nothing`: maximum value used in colormapping data. + +- `wiggle_fill_color=:black`: color for filling the positive wiggles. +- `wiggle_line_color=:black`: color for wiggles' lines. +- `wiggle_trace_increment=1`: increment for wiggle traces. +- `xcur=1.2`: wiggle excursion in traces corresponding to clip. + +- `cmap=:seismic`: the colormap to be used. + +# Examples +```julia +julia> d = SeisLinearEvents(); +julia> f, ax, ov = seisoverlay(d) +``` +```julia +julia> d = SeisLinearEvents(); f = Figure(); ax = Axis(f) +julia> ov = seisoverlay!(ax, d) +``` +""" +@recipe(SeisOverlay, d) do scene Attributes( trace_color = :black, trace_width = 0.7, - gx = nothing, ox = 0, dx = 1, @@ -20,29 +55,24 @@ x = (1, 500), y = (1, 100), - cmap = :viridis + cmap = :seismic ) end -function Makie.plot!(overlay::SeisOverlayBase{<:Tuple{AbstractMatrix{<:Real}}}) - - if !isnothing(overlay.gx[]) - overlay.ox[] = overlay.gx[][1] - overlay.dx[] = (overlay.gx[][end] - overlay.gx[][1]) / length(overlay.gx[]) - end +function Makie.plot!(overlay::SeisOverlay{<:Tuple{AbstractMatrix{<:Real}}}) - seiscolorbase!(overlay, overlay.d[], ox=overlay.ox[], dx=overlay.dx[], oy=overlay.oy[], dy=overlay.dy[], colormap=overlay.cmap[], + seisimage!(overlay, overlay.d[], ox=overlay.ox[], dx=overlay.dx[], oy=overlay.oy[], dy=overlay.dy[], colormap=overlay.cmap[], vmin=overlay.vmin[], vmax=overlay.vmax[], pclip=overlay.pclip[]) - seiswigglebase!(overlay, overlay.d[], gx=overlay.gx[], ox=overlay.ox[], dx=overlay.dx[], oy=overlay.oy[], dy=overlay.dy[], + seiswiggle!(overlay, overlay.d[], ox=overlay.ox[], dx=overlay.dx[], oy=overlay.oy[], dy=overlay.dy[], xcur=overlay.xcur[], wiggle_trace_increment=overlay.wiggle_trace_increment[], trace_color=overlay.trace_color[], trace_width=overlay.trace_width[], fillbands=false) overlay end -function Makie.extract_colormap(pl::Plot{seisoverlaybase, Tuple{Matrix{Float64}}}) - # Return the ColorMapping of the SeisColor plot - # - typeof(pl.plots[1] is seiscolorbase) = Plot{SeisMakie.seiscolorbase, Tuple{Matrix{Float64}}} +function Makie.extract_colormap(pl::Plot{seisoverlay, Tuple{Matrix{Float64}}}) + # Return the ColorMapping of the seisimage plot + # - typeof(pl.plots[1]) = Plot{SeisMakie.seisimage, Tuple{Matrix{<:Real}}} # - typeof(pl.plots[1].plots[1]) = Image{Tuple{ClosedInterval{Float32}, ClosedInterval{Float32}, Matrix{Float32}}} return Makie.extract_colormap(pl.plots[1].plots[1]) end \ No newline at end of file diff --git a/src/Recipes/SeisWiggleRecipe.jl b/src/Recipes/SeisWiggleRecipe.jl index 452b356..72885a3 100644 --- a/src/Recipes/SeisWiggleRecipe.jl +++ b/src/Recipes/SeisWiggleRecipe.jl @@ -1,4 +1,37 @@ -@recipe(SeisWiggleBase, d) do scene +""" + seiswiggle(d; ) + seiswiggle!(ax, d; ) + +Recipe to plot time-space, wiggle plot of 2D seismic data `d`. + +# Arguments: +- `d::Matrix{<:AbstractFloat}`: the measured seismic traces. Number of columns corresponds to number + of traces whereas number of rows corresponds to the number of times + amplitude was measured for each trace + +# Keyword Arguments: +- `gx::Vector{<:Real}=nothing`: the real coordinates of the seismometers corresponding to the traces in d +- `ox=0`: first point of x-axis. +- `dx=1`: increment of x-axis. +- `oy=0`: first point of y-axis. +- `dy=1`: increment of y-axis. + +- `wiggle_fill_color=:black`: color for filling the positive wiggles. +- `wiggle_line_color=:black`: color for wiggles' lines. +- `wiggle_trace_increment=1`: increment for wiggle traces. +- `xcur=1.2`: wiggle excursion in traces. + +# Examples +```julia +julia> d = SeisLinearEvents(); +julia> f, ax, wp = seiswiggle(d) +``` +```julia +julia> d = SeisLinearEvents(); f = Figure(); ax = Axis(f) +julia> wp = seiswiggle!(ax, d) +``` +""" +@recipe(SeisWiggle, d) do scene Attributes( wiggle_line_color = :black, wiggle_fill_color = :black, @@ -14,13 +47,13 @@ xcur = 1.2, wiggle_trace_increment = 1, - #wiggle_difference = 1, + wiggle_difference = 1, fillbands = true, ) end -function Makie.plot!(wp::SeisWiggleBase{<:Tuple{AbstractMatrix{<:Real}}}) +function Makie.plot!(wp::SeisWiggle{<:Tuple{AbstractMatrix{<:Real}}}) d = wp.d gx = wp.gx From 6a5266fc54af123d78bbe891b6573336204b798b Mon Sep 17 00:00:00 2001 From: Firas Date: Tue, 20 Feb 2024 02:29:08 -0700 Subject: [PATCH 16/22] Merged wrappers into SeisPlotTX --- src/SeisColor.jl | 44 ------------------------------------- src/SeisOverlay.jl | 55 ---------------------------------------------- src/SeisPlotTX.jl | 46 +++++++++++++++++++++++++++++--------- src/SeisWiggle.jl | 53 -------------------------------------------- 4 files changed, 36 insertions(+), 162 deletions(-) delete mode 100644 src/SeisColor.jl delete mode 100644 src/SeisOverlay.jl delete mode 100644 src/SeisWiggle.jl diff --git a/src/SeisColor.jl b/src/SeisColor.jl deleted file mode 100644 index 732ca64..0000000 --- a/src/SeisColor.jl +++ /dev/null @@ -1,44 +0,0 @@ -""" - SeisColor(d; ) - -Plot time-space, color plot of 2D seismic data `d`. - -# Arguments: -- `d::Matrix{<:AbstractFloat}`: 2D seismic data to be plotted. - -# Keyword Arguments: -- `fig::Figure=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. - -- `ox=0`: first point of x-axis. -- `dx=1`: increment of x-axis. -- `oy=0`: first point of y-axis. -- `dy=1`: increment of y-axis. - -- `pclip=98`: percentile for determining clip. -- `vmin=nothing`: minimum value used in colormapping data. -- `vmax=nothing`: maximum value used in colormapping data. - -- `cmap=:viridis`: the colormap to be used. - -Return the figure and axis corresponding to d. - -# Example -```julia -julia> d = SeisLinearEvents(); SeisColor(d); -``` -""" -function SeisColor(d; - fig=nothing, ox=0, dx=1, oy=0, dy=1, - pclip=98, vmin=nothing, vmax=nothing, cmap=:viridis, kwargs...) - - if isnothing(fig) - fig = Figure() - end - - ax = __create_axis(fig[1,1]) - xlims!(ax, low=ox-dx, high=ox+size(d,2)*dx) - img = seiscolorbase!(ax, d, ox=ox, dx=dx, oy=oy, dy=dy, pclip=pclip, vmin=vmin, vmax=vmax, cmap=cmap) - Colorbar(fig[1,2], img) - - return fig, ax -end \ No newline at end of file diff --git a/src/SeisOverlay.jl b/src/SeisOverlay.jl deleted file mode 100644 index 3f7ad86..0000000 --- a/src/SeisOverlay.jl +++ /dev/null @@ -1,55 +0,0 @@ -""" - SeisOverlay(d; ) - -Plot time-space, overlay plot of 2D seismic data `d`. - -# Arguments: -- `d::Matrix{<:AbstractFloat}`: 2D seismic data to be plotted. - -# Keyword Arguments: -- `fig::Figure=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. - -- `gx::Vector{<:Real}=nothing`: the real coordinates of the seismometers corresponding to the traces in d -- `ox=0`: first point of x-axis. -- `dx=1`: increment of x-axis. -- `oy=0`: first point of y-axis. -- `dy=1`: increment of y-axis. - -- `pclip=98`: percentile for determining clip. -- `vmin=nothing`: minimum value used in colormapping data. -- `vmax=nothing`: maximum value used in colormapping data. - -- `wiggle_fill_color=:black`: color for filling the positive wiggles. -- `wiggle_line_color=:black`: color for wiggles' lines. -- `wiggle_trace_increment=1`: increment for wiggle traces. -- `xcur=1.2`: wiggle excursion in traces corresponding to clip. - -- `cmap=:viridis`: the colormap to be used. - -Return the figure and axis corresponding to d. - -# Example -```julia -julia> d = SeisLinearEvents(); SeisOverlay(d); -``` -""" -function SeisOverlay(d; - fig=nothing, ox=0, dx=1, oy=0, dy=1, gx=nothing, xcur=1.2, wiggle_trace_increment=1, - pclip=98, vmin=nothing, vmax=nothing, - wiggle_line_color=:black, wiggle_fill_color=:black,trace_width=0.7, - cmap=:viridis, kwargs...) - - if isnothing(fig) - fig = Figure() - end - - ax = __create_axis(fig[1, 1]) - xlims!(ax, low=ox-dx, high=ox+size(d,2)*dx) - overlay = seisoverlaybase!(ax, d, ox=ox, dx=dx, oy=oy, dy=dy, gx=gx, pclip=pclip, vmin=vmin, vmax=vmax, xcur=xcur, - wiggle_trace_increment=wiggle_trace_increment, wiggle_line_color=wiggle_line_color, - wiggle_fill_color=wiggle_fill_color, trace_width=trace_width, cmap=cmap) - - Colorbar(fig[1, 2], overlay) - - return fig, ax -end \ No newline at end of file diff --git a/src/SeisPlotTX.jl b/src/SeisPlotTX.jl index 05a4900..5d0f138 100644 --- a/src/SeisPlotTX.jl +++ b/src/SeisPlotTX.jl @@ -1,7 +1,7 @@ """ SeisPlotTX(d; ) -Plot time-space, 2D seismic data `d` with color, wiggles or overlay. +Plot time-space, 2D seismic data `d` with image, wiggles or overlay. # Arguments: - `d::Matrix{<:AbstractFloat}`: the measured seismic traces. Number of columns corresponds to number @@ -9,7 +9,7 @@ Plot time-space, 2D seismic data `d` with color, wiggles or overlay. amplitude was measured for each trace # Keyword Arguments: -- `fig::Figure=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. +- `fig=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. - `gx::Vector{<:Real}=nothing`: the real coordinates of the seismometers corresponding to the traces in d - `ox=0`: first point of x-axis. @@ -26,26 +26,52 @@ Plot time-space, 2D seismic data `d` with color, wiggles or overlay. - `wiggle_trace_increment=1`: increment for wiggle traces. - `xcur=1.2`: wiggle excursion in traces corresponding to clip. -- `colormap=:viridis`: the colormap to be used for color and overlay plots. +- `cmap=:seismic`: the colormap to be used for image and overlay plots. -- `style`: determines the type of plot. Can be either "wiggle"/"wiggles", "color", "overlay". +- `style`: determines the type of plot. Can be either "wiggle"/"wiggles", "image", "overlay". Return the figure and axis corresponding to d. # Example ```julia -julia> d = SeisLinearEvents(); SeisPlotTX(d); +julia> d = SeisLinearEvents(); +julia> f, ax = SeisPlotTX(d); ``` """ -function SeisPlotTX(d; style="color", kwargs...) +function SeisPlotTX(d; + fig=nothing, gx=nothing, ox=0, dx=1, oy=0, dy=1, xcur=1.2, wiggle_trace_increment=1, + pclip=98, vmin=nothing, vmax=nothing, + wiggle_line_color=:black, wiggle_fill_color=:black,trace_width=0.7, + cmap=:seismic, style="image") + + if isnothing(fig) + fig = Figure() + end + + ax = __create_axis(fig[1,1]) if style == "overlay" - return SeisOverlay(d; kwargs...) + overlay = seisoverlay!(ax, d; ox=ox, dx=dx, oy=oy, dy=dy, pclip=pclip, vmin=vmin, vmax=vmax, xcur=xcur, + wiggle_trace_increment=wiggle_trace_increment, wiggle_line_color=wiggle_line_color, + wiggle_fill_color=wiggle_fill_color, trace_width=trace_width, cmap=cmap) + + Colorbar(fig[1, 2], overlay) elseif style == "wiggles" || style == "wiggle" - return SeisWiggle(d; kwargs...) - else - return SeisColor(d; kwargs...) + if !isnothing(gx) + ox = gx[1] + dx = minimum([gx[i]-gx[i-1] for i = 2:length(gx)]) + end + + seiswiggle!(ax, d; gx=gx, ox=ox, dx=dx, oy=oy, dy=dy, xcur=xcur, wiggle_trace_increment=wiggle_trace_increment, + wiggle_line_color=wiggle_line_color, wiggle_fill_color=wiggle_fill_color, + trace_width=trace_width) + else + img = seisimage!(ax, d; ox=ox, dx=dx, oy=oy, dy=dy, pclip=pclip, vmin=vmin, vmax=vmax, cmap=cmap) + Colorbar(fig[1,2], img) end + xlims!(ax, low=ox-dx, high=ox+size(d,2)*dx) + return fig, ax + end diff --git a/src/SeisWiggle.jl b/src/SeisWiggle.jl deleted file mode 100644 index fe973ab..0000000 --- a/src/SeisWiggle.jl +++ /dev/null @@ -1,53 +0,0 @@ -""" - SeisWiggle(d; ) - -Plot time-space, wiggle plot of 2D seismic data `d`. - -# Arguments: -- `d::Matrix{<:AbstractFloat}`: the measured seismic traces. Number of columns corresponds to number - of traces whereas number of rows corresponds to the number of times - amplitude was measured for each trace - -# Keyword Arguments: -- `fig::Figure=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. - -- `gx::Vector{<:Real}=nothing`: the real coordinates of the seismometers corresponding to the traces in d -- `ox=0`: first point of x-axis. -- `dx=1`: increment of x-axis. -- `oy=0`: first point of y-axis. -- `dy=1`: increment of y-axis. - -- `wiggle_fill_color=:black`: color for filling the positive wiggles. -- `wiggle_line_color=:black`: color for wiggles' lines. -- `wiggle_trace_increment=1`: increment for wiggle traces. -- `xcur=1.2`: wiggle excursion in traces. - -Return the figure and axis corresponding to d. - -# Example -```julia -julia> d = SeisLinearEvents(); SeisWiggle(d); -``` -""" -function SeisWiggle(d; - fig=nothing, gx=nothing, ox=0, dx=1, oy=0, dy=1, - xcur=1.2, wiggle_trace_increment=1, trace_width=0.7, - wiggle_line_color=:black, wiggle_fill_color=:black, - kwargs...) - - if isnothing(fig) - fig = Figure() - end - - ax = __create_axis(fig[1,1]) - if !isnothing(gx) - ox = gx[1] - dx = minimum([gx[i]-gx[i-1] for i = 2:length(gx)]) - end - xlims!(ax, low=ox-dx, high=ox+size(d,2)*dx) - seiswigglebase!(ax, d, gx=gx, ox=ox, dx=dx, oy=oy, dy=dy, xcur=xcur, wiggle_trace_increment=wiggle_trace_increment, - wiggle_line_color=wiggle_line_color, wiggle_fill_color=wiggle_fill_color, - trace_width=trace_width) - - return fig, ax -end \ No newline at end of file From a12742e6109262634f89dca65d224627b2415bae Mon Sep 17 00:00:00 2001 From: Firas Date: Tue, 20 Feb 2024 02:32:30 -0700 Subject: [PATCH 17/22] Added amplitude plotting recipe and its wrapper --- src/Recipes/SeisAmplitudeRecipe.jl | 65 ++++++++++++++++++++++++++++++ src/SeisPlotAmplitude.jl | 45 +++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 src/Recipes/SeisAmplitudeRecipe.jl create mode 100644 src/SeisPlotAmplitude.jl diff --git a/src/Recipes/SeisAmplitudeRecipe.jl b/src/Recipes/SeisAmplitudeRecipe.jl new file mode 100644 index 0000000..9b416ae --- /dev/null +++ b/src/Recipes/SeisAmplitudeRecipe.jl @@ -0,0 +1,65 @@ +""" + seisamplitude(d; ) + seisamplitude!(ax, d; ) + +Plot amplitude-frequency 2D seismic data `d`. + + +# Arguments +- `d::Array{Real,2}`: 2D data to plot. + +# Keyword arguments +- `fmax=100`: maximum frequency. +- `dy=0.004`: time sample interval. +- `normalize=false`: whether or not to normalize the data + +- `color=:black`: color of the plot. +- `label=""`: plot label to be included in legend + +# Examples +```julia +julia> d = SeisLinearEvents(); +julia> f, ax, amp = seisamplitude(d) +``` +```julia +julia> d = SeisLinearEvents(); f = Figure(); ax = Axis(f) +julia> amp = seisamplitude!(ax, d) +``` +""" +@recipe(SeisAmplitude, d) do scene + Attributes( + fmax=100, + dy=0.004, + + normalize=false, + + color = :black, + label = "", + ) +end + +function Makie.plot!(amp::SeisAmplitude{<:Tuple{AbstractMatrix{<:Real}}}) + + nx = size(amp.d[], 2) + df = 1/amp.dy[]/size(amp.d[], 1) + FMAX = df*size(amp.d[], 1)/2 + if amp.fmax[] > FMAX + amp.fmax[] = FMAX + end + nf = convert(Int32, floor((size(amp.d[], 1)/2)*amp.fmax[]/FMAX)) + y = fftshift(sum(abs.(fft(amp.d[], 1)), dims=2))/nx + y = y[round(Int,end/2):round(Int, end/2)+nf] + + if amp.normalize[] + norm = maximum(y[:]) + if (norm > 0.) + y = y/norm + end + end + + x = collect(0:df:amp.fmax[]) + + lines!(amp, x, y, color=amp.color[], label=amp.label[]) + + amp +end diff --git a/src/SeisPlotAmplitude.jl b/src/SeisPlotAmplitude.jl new file mode 100644 index 0000000..3ad938d --- /dev/null +++ b/src/SeisPlotAmplitude.jl @@ -0,0 +1,45 @@ +""" + SeisPlotAmplitude(d,fmax,dy ; ) + +Plot amplitude-frequency 2D seismic data `d` + + +# Arguments +- `d::Array{Real,2}`: 2D data to plot. + +# Keyword arguments +- `fig=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. +- `ax=nothing`: the axis we want to plot on. If not supplied, one will be created and returned. + +- `fmax=100`: maximum frequency. +- `dy=0.004`: time sample interval. +- `normalize=false`: whether or not to normalize the data + +- `color=:red`: color of the plot. +- `label=""`: plot label to be included in legend + +# Example +```julia +julia> d = SeisLinearEvents(); +julia> f, ax = SeisPlotAmplitude(d,100,0.004); +``` +""" +function SeisPlotAmplitude(d::Array{<:Real, 2}; fig=nothing, ax=nothing, fmax=100, dy=0.004, + normalize=false, color=:black, label="") + + if isnothing(fig) + fig = Figure() + end + + if isnothing(ax) + ax = Axis(fig[1,1]) + ax.title = "Amplitude Spectrum" + ax.xlabel = "Frequency (Hz)" + ax.ylabel = "Amplitude" + ax.xgridvisible = true + end + + seisamplitude!(ax, d, fmax=fmax, dy=dy, normalize=normalize, color=color, label=label) + + return fig, ax +end \ No newline at end of file From b6e24ad1901ac93a30da5f9ecdf306f765cd7807 Mon Sep 17 00:00:00 2001 From: Firas Date: Tue, 20 Feb 2024 02:33:32 -0700 Subject: [PATCH 18/22] Added a recipe for SeisPlotFK and updated wrapper accordingly --- src/Recipes/SeisFKRecipe.jl | 80 +++++++++++++++++++++++++++++++++++++ src/SeisPlotFK.jl | 35 +++------------- 2 files changed, 85 insertions(+), 30 deletions(-) create mode 100644 src/Recipes/SeisFKRecipe.jl diff --git a/src/Recipes/SeisFKRecipe.jl b/src/Recipes/SeisFKRecipe.jl new file mode 100644 index 0000000..fd4b4a5 --- /dev/null +++ b/src/Recipes/SeisFKRecipe.jl @@ -0,0 +1,80 @@ +""" + seisfk(d; ) + seisfk!(ax, d; ) + +Plot time-space, frequency-wavenumber or amplitude-frequency 2D seismic data `d` +with color, wiggles or overlay. + +# Arguments +- `d::Matrix{<:AbstractFloat}`: 2D data to plot. + +# Keyword arguments: +- `fig=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. + +- `pclip=99.9`: percentile for determining clip. +- `vmin=nothing`: minimum value used in colormapping data. +- `vmax=nothing`: maximum value used in colormapping data. + +- `fmax=100`: maximum frequency for `"FK"` or `"Amplitude"` plot. + +- `dx=1`: increment of x-axis. +- `dy=1`: increment of y-axis. + +- `cmap=:PuOr`: colormap for `"color"` or `"overlay"` style. + +Return the figure and axis corresponding to d. + +# Examples +```julia +julia> d = SeisLinearEvents(); +julia> f, ax, fk = seisfk(d) +``` +```julia +julia> d = SeisLinearEvents(); f = Figure(); ax = Axis(f) +julia> fk = seisfk!(ax, d) +``` +""" +@recipe(SeisFK, d) do scene + Attributes( + dx=1, + dy=1, + fmax=100, + + pclip=99.9, + vmin=nothing, + vmax=nothing, + + cmap=:PuOr + ) +end + +function Makie.plot!(fk::SeisFK{<:Tuple{AbstractMatrix{<:Real}}}) + + dk = 1/fk.dx[]/size(fk.d[], 2) + kmin = -dk*size(fk.d[], 2)/2 + kmax = dk*size(fk.d[], 2)/2 + + df = 1/fk.dy[]/size(fk.d[], 1) + FMAX = df*size(fk.d[], 1)/2 + if fk.fmax[] > FMAX + fk.fmax[] = FMAX + end + nf = convert(Int32, floor((size(fk.d[], 1)/2)*fk.fmax[]/FMAX)) + D = abs.(fftshift(fft(fk.d[]))) + D = D[round(Int,end/2):round(Int,end/2)+nf, :] + + if (isnothing(fk.vmin[]) || isnothing(fk.vmax[])) + a = 0. + if (fk.pclip[] <= 100) + b = quantile(abs.(D[:]), (fk.pclip[]/100)) + else + b = quantile(abs.(D[:]), 1)*fk.pclip[]/100 + end + else + a = fk.vmin[] + b = fk.vmax[] + end + + image!(fk, (kmin, kmax), (0.0, fk.fmax[]), D', colorrange=(a, b), colormap=fk.cmap[]) + +end diff --git a/src/SeisPlotFK.jl b/src/SeisPlotFK.jl index 1d625bf..e04a5fc 100644 --- a/src/SeisPlotFK.jl +++ b/src/SeisPlotFK.jl @@ -8,7 +8,7 @@ with color, wiggles or overlay. - `d::Matrix{<:AbstractFloat}`: 2D data to plot. # Keyword arguments: -- `fig::Figure=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. +- `fig=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. - `pclip=99.9`: percentile for determining clip. - `vmin=nothing`: minimum value used in colormapping data. @@ -16,9 +16,7 @@ with color, wiggles or overlay. - `fmax=100`: maximum frequency for `"FK"` or `"Amplitude"` plot. -- `ox=0`: first point of x-axis. - `dx=1`: increment of x-axis. -- `oy=0`: first point of y-axis. - `dy=1`: increment of y-axis. - `cmap=:PuOr`: colormap for `"color"` or `"overlay"` style. @@ -27,10 +25,11 @@ Return the figure and axis corresponding to d. # Example ```julia -julia> d = SeisLinearEvents(); SeisPlotFK(d); +julia> d = SeisLinearEvents(); +julia> f, ax = SeisPlotFK(d); ``` """ -function SeisPlotFK(d; fig=nothing, ox=0, dx=1, oy=0, dy=1, fmax=100, +function SeisPlotFK(d; fig=nothing, dx=1, dy=1, fmax=100, pclip=99.9, vmin=nothing, vmax=nothing, cmap=:PuOr) if isnothing(fig) @@ -39,31 +38,7 @@ function SeisPlotFK(d; fig=nothing, ox=0, dx=1, oy=0, dy=1, fmax=100, ax = __create_axis(fig[1, 1]) - dk = 1/dx/size(d, 2) - kmin = -dk*size(d, 2)/2 - kmax = dk*size(d, 2)/2 - - df = 1/dy/size(d, 1) - FMAX = df*size(d, 1)/2 - if fmax > FMAX - fmax = FMAX - end - nf = convert(Int32, floor((size(d, 1)/2)*fmax/FMAX)) - D = abs.(fftshift(fft(d))) - D = D[round(Int,end/2):round(Int,end/2)+nf, :] - if (isnothing(vmin) || isnothing(vmax)) - a = 0. - if (pclip<=100) - b = quantile(abs.(D[:]), (pclip/100)) - else - b = quantile(abs.(D[:]), 1)*pclip/100 - end - else - a = vmin - b = vmax - end - - image!(ax, (kmin, kmax), (0.0, 0.5), D', colorrange=(a, b), colormap=:PuOr) + seisfk!(ax, d, dx=dx, dy=dy, fmax=fmax, pclip=pclip, vmin=vmin, vmax=vmax, cmap=cmap) ax.xlabel = "Wavenumber (1/m)" ax.ylabel = "Frequency (Hz)" From c07bb81cc3b03ad55fe9977e9fa95783caf130e0 Mon Sep 17 00:00:00 2001 From: Firas Date: Tue, 20 Feb 2024 02:34:04 -0700 Subject: [PATCH 19/22] Difference plots can now be plotted horizontally or vertically --- src/SeisDifference.jl | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/SeisDifference.jl b/src/SeisDifference.jl index ba6a1ed..90d9242 100644 --- a/src/SeisDifference.jl +++ b/src/SeisDifference.jl @@ -2,6 +2,7 @@ SeisDifference(d1, d2; ) Plot time-space, 2D seismic data `d1`, `d2`, and their difference (`d1 - d2`) with color, wiggles or overlay. +The plots are arranged horizontally by default. # Arguments: - `d1::Matrix{<:AbstractFloat}`: the measured seismic traces. Number of columns corresponds to number @@ -10,7 +11,7 @@ Plot time-space, 2D seismic data `d1`, `d2`, and their difference (`d1 - d2`) wi - `d2::Matrix{<:AbstractFloat}`: same description as d1. # Keyword Arguments: -- `fig::Figure=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. +- `fig=nothing`: the figure we want to plot on. If not supplied, one will be created and returned. - `gx::Vector{<:Real}=nothing`: the real coordinates of the seismometers corresponding to the traces in d - `ox=0`: first point of x-axis. @@ -30,46 +31,54 @@ Plot time-space, 2D seismic data `d1`, `d2`, and their difference (`d1 - d2`) wi - `cmap=:viridis`: the colormap to be used for color and overlay plots. - `style`: determines the type of plot. Can be either "wiggle"/"wiggles", "color", "overlay". +- `horizontal=true`: if set to false, d1, d2, and their difference are arranged vertically. Return the figure and 3 axes corresponding to d1, d2, d1-d2. # Example ```julia -julia> d1 = SeisLinearEvents(); d2 = SeisLinearEvents(); SeisDifference(d1, d2); +julia> d1 = SeisLinearEvents(); d2 = SeisLinearEvents(); +julia> f, ax1, ax2, ax_diff = SeisDifference(d1, d2); ``` """ function SeisDifference(d1, d2; fig=nothing, ox=0, dx=1, oy=0, dy=1, gx=nothing, pclip=98, vmin=nothing, vmax=nothing, wiggle_line_color=:black, - wiggle_fill_color=:black, trace_width=0.7, cmap=:viridis, style="overlay") + wiggle_fill_color=:black, trace_width=0.7, cmap=:viridis, style="overlay", horizontal=true) if isnothing(fig) fig = Figure() end if style == "overlay" - plotfunc = seisoverlaybase! + plotfunc = seisoverlay! elseif style == "wiggles" || style == "wiggle" - plotfunc = seiswigglebase! + plotfunc = seiswiggle! else - plotfunc = seiscolorbase! + plotfunc = seiscolor! end - axes = [__create_axis(fig[1, 1], ), __create_axis(fig[2, 1]), __create_axis(fig[1, 3])] - data = [d1, d2, d1 .- d2] + if horizontal == true + axes = [__create_axis(fig[1, 1]), __create_axis(fig[1, 2]), __create_axis(fig[1, 3])] + else + axes = [__create_axis(fig[1, 1]), __create_axis(fig[2, 1]), __create_axis(fig[3, 1])] + end + data = [d1, d2, d1 .- d2 ] plots = [] for (i, ax) in enumerate(axes) - xlims!(ax, low=ox-dx, high=ox+size(d,2)*dx) + xlims!(ax, low=ox-dx, high=ox+size(d1,2)*dx) push!(plots, plotfunc(ax, data[i], ox=ox, dx=dx, oy=oy, dy=dy, gx=gx, pclip=pclip, vmin=vmin, vmax=vmax, wiggle_line_color=wiggle_line_color, wiggle_fill_color=wiggle_fill_color, trace_width=trace_width, cmap=cmap)) end if !(style == "wiggles" || style == "wiggle") - Colorbar(fig[1, 2], plots[1]) - Colorbar(fig[2, 2], plots[2]) - Colorbar(fig[1, 4], plots[3]) + if horizontal + Colorbar(fig[1, 4], plots[1]) + else + Colorbar(fig[1:3, 2], plots[1]) + end end return fig, axes[1], axes[2], axes[3] From 91dfe159d2faad1dc4ca9658607eae13202c01bd Mon Sep 17 00:00:00 2001 From: Firas Date: Tue, 20 Feb 2024 02:34:35 -0700 Subject: [PATCH 20/22] Updated exports to include new recipes --- src/SeisMakie.jl | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/SeisMakie.jl b/src/SeisMakie.jl index 4853f33..e4679d9 100644 --- a/src/SeisMakie.jl +++ b/src/SeisMakie.jl @@ -7,26 +7,33 @@ module SeisMakie using FFTW include("Recipes/SeisWiggleRecipe.jl") - include("Recipes/SeisColorRecipe.jl") + include("Recipes/SeisImageRecipe.jl") include("Recipes/SeisOverlayRecipe.jl") + include("Recipes/SeisAmplitudeRecipe.jl") + include("Recipes/SeisFKRecipe.jl") - include("SeisWiggle.jl") - include("SeisOverlay.jl") - include("SeisColor.jl") include("SeisDifference.jl") - include("SeisPlotFK.jl") include("SeisPlotTX.jl") + include("SeisPlotAmplitude.jl") include("Util.jl") - - export SeisWiggle - export SeisColor - export SeisOverlay + + export seisamplitude + export seisamplitude! + export seisfk + export seisfk! + export seisimage + export seisimage! + export seisoverlay + export seisoverlay! + export seiswiggle + export seiswiggle! export SeisDifference export SeisPlotTX export SeisPlotFK + export SeisPlotAmplitude end From 18e5237afec0c76b1c2924b4b696d2c799c62c4c Mon Sep 17 00:00:00 2001 From: Firas Date: Tue, 20 Feb 2024 02:35:00 -0700 Subject: [PATCH 21/22] Updated examples to reflect changes --- examples/tutorialSeisMakie.jl | 121 ++++++++++++++++++++++------------ 1 file changed, 79 insertions(+), 42 deletions(-) diff --git a/examples/tutorialSeisMakie.jl b/examples/tutorialSeisMakie.jl index 6d7c2f0..976efcb 100644 --- a/examples/tutorialSeisMakie.jl +++ b/examples/tutorialSeisMakie.jl @@ -36,26 +36,29 @@ begin nothing end +# ╔═╡ c25286cd-82b5-4725-96cc-4ab6ed0aa121 +begin + f1, ax1 = SeisPlotTX(D, style="wiggle") + f1 +end + # ╔═╡ 26992493-fe50-4f59-8141-9ea9e8606516 # ╔═╡ abe64b2a-f192-4e3b-ba3e-f26286b1a38d md""" -## SeisWiggle +## SeisPlotTX """ -# ╔═╡ c25286cd-82b5-4725-96cc-4ab6ed0aa121 -begin - f1, ax1 = SeisWiggle(D) - f1 -end +# ╔═╡ 0c3fcf92-8924-49ac-b487-a9dc372b2739 + # ╔═╡ 25c72bf7-28ce-4f6b-b4c4-24be2f51a5f9 begin function start_and_interval() ox, dx = 1000, 3 oy, dy = 500, 5 - f, ax = SeisWiggle(D, ox=ox, dx=dx, oy=oy, dy=dy) + f, ax = SeisPlotTX(D, ox=ox, dx=dx, oy=oy, dy=dy, style="wiggle") f end start_and_interval() @@ -73,7 +76,7 @@ begin gx = gx[p] d = d[:, p] - f, ax = SeisWiggle(d, gx=gx) + f, ax = SeisPlotTX(d, gx=gx, style="wiggle") f end real_coords() @@ -82,7 +85,7 @@ end # ╔═╡ 38fcc0c0-aaaa-4777-b67c-9cc5c9289a91 begin function excursion() - f, ax = SeisWiggle(D, xcur=5) + f, ax = SeisPlotTX(D, xcur=5, style="wiggle") f end excursion() @@ -91,7 +94,7 @@ end # ╔═╡ 9a61b3d7-3a77-417d-b60b-7172050167e4 begin function trace_increment() - f, ax = SeisWiggle(D, wiggle_trace_increment=4) + f, ax = SeisPlotTX(D, wiggle_trace_increment=4, style="wiggle") f end trace_increment() @@ -100,7 +103,7 @@ end # ╔═╡ e6f38a8d-3db9-47ed-801e-2f434d2ef70c begin function formatting() - f, ax = SeisWiggle(D, wiggle_trace_increment=4, wiggle_line_color=:orange, wiggle_fill_color=:purple) + f, ax = SeisPlotTX(D, wiggle_trace_increment=4, wiggle_line_color=:orange, wiggle_fill_color=:purple, style="wiggle") f end formatting() @@ -108,13 +111,13 @@ end # ╔═╡ a66db96a-a6f1-4628-8a89-d8b2744eb3b5 md""" -## SeisColor +### SeisColor """ # ╔═╡ 0a63424d-ab08-4dd4-bff8-5239ec312733 begin function base_color() - f, ax = SeisColor(D) + f, ax = SeisPlotTX(D, style="color") f end base_color() @@ -123,7 +126,7 @@ end # ╔═╡ a546c9bc-7d20-4636-850f-f900194e97e8 begin function with_pclip() - f, ax = SeisColor(D, pclip=95) + f, ax = SeisPlotTX(D, pclip=95, style="color") f end dx = 1 @@ -133,7 +136,7 @@ end # ╔═╡ 9aff572e-683c-4085-878f-8c87c046db6f begin function with_vmin_vmax() - f, ax = SeisColor(D, vmin=-0.1, vmax=0.4) + f, ax = SeisPlotTX(D, vmin=-0.1, vmax=0.4, style="color") f end with_vmin_vmax() @@ -142,7 +145,7 @@ end # ╔═╡ 21cb4890-628a-4331-a163-77fd8b3c9e05 begin function with_different_colormap() - f, ax = SeisColor(D, colormap=:seismic) + f, ax = SeisPlotTX(D, cmap=:seismic, style="color") f end with_different_colormap() @@ -150,14 +153,14 @@ end # ╔═╡ 526287c9-8d28-4357-8313-6f7ba2f2f49b md""" -## SeisOverlay +### SeisOverlay You can use a combination of the arguments supplied to SeisWiggle and SeisColor """ # ╔═╡ 312a0197-d66c-436d-9452-7c70e4cfaded begin function base_overlay() - f, ax = SeisOverlay(D) + f, ax = SeisPlotTX(D, style="overlay") f end base_overlay() @@ -166,27 +169,12 @@ end # ╔═╡ 483422b0-666b-4600-a96b-9dd84ca19298 begin function overlay_with_args() - f, ax = SeisOverlay(D, ox=20, dx=10, oy=500, dy=3, colormap=:seismic, vmin=-0.2, vmax=0.3) + f, ax = SeisPlotTX(D, ox=20, dx=10, oy=500, dy=3, cmap=:seismic, vmin=-0.2, vmax=0.3, style="overlay") f end overlay_with_args() end -# ╔═╡ 2b231e00-8952-4bfc-b26e-79abcc6258e9 -md""" -## SeisPlotTX -Based on request. Pass in the arguments you want along with a `style` keyword. `style` can be one of "wiggle", "overlay", "color". -""" - -# ╔═╡ 6ccaf31a-caa8-4118-861d-9dd960b28d73 -begin - function seisplottx_demo() - f, ax = SeisPlotTX(D, style="overlay") - f - end - seisplottx_demo() -end - # ╔═╡ ee40ceea-7d3f-4578-902d-d1518f4c7c84 md""" ## SeisPlotFK @@ -211,7 +199,7 @@ You can edit axes as shown below. For more info, go to: https://docs.makie.org/s begin function modifying_axis() # All the functions mentioned above return an axis that can be edited - f, ax = SeisOverlay(D, pclip=97) + f, ax = SeisPlotTX(D, pclip=97) ax.title = "Overlay Plot (SeisMakie)" ax.xlabel = "Trace Number" ax.ylabel = "Time (s)" @@ -233,9 +221,9 @@ begin # by the first function. The position of the axis on the figure is indexed as # shown below f = Figure() - _, wiggle_ax = SeisWiggle(D, fig=f[1,1], wiggle_trace_increment=4) - _, color_ax = SeisColor(D, fig=f[2, 1]) - _, overlay_ax = SeisOverlay(D, fig=f[1,2], wiggle_trace_increment=4) + _, wiggle_ax = SeisPlotTX(D, fig=f[1,1], wiggle_trace_increment=4, style="wiggle") + _, color_ax = SeisPlotTX(D, fig=f[2, 1], style="color") + _, overlay_ax = SeisPlotTX(D, fig=f[1,2], wiggle_trace_increment=4, style="overlay") wiggle_ax.title = "Wiggle" color_ax.title = "Color" @@ -258,20 +246,67 @@ begin end end -# ╔═╡ f2ac7e44-7a07-4956-9f22-526af10d1fe0 +# ╔═╡ 55151c58-ce42-4473-8bee-6ae501b5a891 +md""" +## SeisPlotAmplitude +""" +# ╔═╡ f2ac7e44-7a07-4956-9f22-526af10d1fe0 +begin + function spamplitude() + f, ax = SeisPlotAmplitude(D) + f + end + spamplitude() +end # ╔═╡ 1fcb8085-02f2-4907-999a-19db73ce4563 +begin + function spamplitude_multiple() + f, ax = SeisPlotAmplitude(D, label="D") + SeisPlotAmplitude(D1, ax=ax, label="D1") + SeisPlotAmplitude(D2, ax=ax, label="D2") + axislegend(ax, pos = :tr) # Top right position + #Legend(f[1, 2], ax) + f + end + spamplitude_multiple() +end +# ╔═╡ 9ceb6a8a-9235-49af-94ae-aa762e96aff0 +md""" +## SeisDifference +""" + +# ╔═╡ 7bad9eb6-9201-4642-b147-193fbb5702fd +begin + function horizontal_diff() + f, ax = SeisDifference(D1, D2) + f + end + horizontal_diff() + +end + +# ╔═╡ ab183ae7-8e20-4413-b4f4-68000038974c +begin + function vertical_diff() + f, ax1, ax2, ax3 = SeisDifference(D1, D2, horizontal=false) + f + end + vertical_diff() + +end # ╔═╡ Cell order: # ╠═93296b66-bca6-11ee-0787-99798c15a928 +# ╠═c25286cd-82b5-4725-96cc-4ab6ed0aa121 # ╠═90077fbb-2384-4d12-b51a-f52758049e49 # ╠═62e31cae-8deb-49a5-a6a1-54a772b48ff6 # ╠═e12751b3-0c8d-4655-b606-ae94d670b0d0 # ╠═26992493-fe50-4f59-8141-9ea9e8606516 # ╠═abe64b2a-f192-4e3b-ba3e-f26286b1a38d -# ╠═c25286cd-82b5-4725-96cc-4ab6ed0aa121 +# ╠═0c3fcf92-8924-49ac-b487-a9dc372b2739 # ╠═25c72bf7-28ce-4f6b-b4c4-24be2f51a5f9 # ╠═13980acc-8aa1-4d87-ab7e-c1a599e0483d # ╠═38fcc0c0-aaaa-4777-b67c-9cc5c9289a91 @@ -285,8 +320,6 @@ end # ╠═526287c9-8d28-4357-8313-6f7ba2f2f49b # ╠═312a0197-d66c-436d-9452-7c70e4cfaded # ╠═483422b0-666b-4600-a96b-9dd84ca19298 -# ╠═2b231e00-8952-4bfc-b26e-79abcc6258e9 -# ╠═6ccaf31a-caa8-4118-861d-9dd960b28d73 # ╠═ee40ceea-7d3f-4578-902d-d1518f4c7c84 # ╠═e12d35e5-4ea6-42f4-a396-92e4d4ebc5c7 # ╠═3947a6c1-4bbe-4ee0-a3e6-114e481dc49c @@ -295,5 +328,9 @@ end # ╠═cf728878-fefb-4d46-a52e-1d0820248d35 # ╠═01db2622-4b44-492d-a0f6-838018727e75 # ╠═8dcce330-fad7-4dde-86c9-f3c732089278 +# ╠═55151c58-ce42-4473-8bee-6ae501b5a891 # ╠═f2ac7e44-7a07-4956-9f22-526af10d1fe0 # ╠═1fcb8085-02f2-4907-999a-19db73ce4563 +# ╠═9ceb6a8a-9235-49af-94ae-aa762e96aff0 +# ╠═7bad9eb6-9201-4642-b147-193fbb5702fd +# ╠═ab183ae7-8e20-4413-b4f4-68000038974c From 3832e9d092c6a586bbd2883e8cebdca1aa634853 Mon Sep 17 00:00:00 2001 From: Firas Date: Thu, 22 Feb 2024 12:38:22 -0700 Subject: [PATCH 22/22] Added feature to plot increments of wiggle traces when real coordinates are supplied --- src/Recipes/SeisWiggleRecipe.jl | 26 ++++++++++++++++---------- src/SeisPlotTX.jl | 2 +- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/Recipes/SeisWiggleRecipe.jl b/src/Recipes/SeisWiggleRecipe.jl index 72885a3..baff36e 100644 --- a/src/Recipes/SeisWiggleRecipe.jl +++ b/src/Recipes/SeisWiggleRecipe.jl @@ -47,7 +47,6 @@ julia> wp = seiswiggle!(ax, d) xcur = 1.2, wiggle_trace_increment = 1, - wiggle_difference = 1, fillbands = true, ) @@ -67,9 +66,8 @@ function Makie.plot!(wp::SeisWiggle{<:Tuple{AbstractMatrix{<:Real}}}) xcur = wp.xcur[] wiggle_trace_increment = wp.wiggle_trace_increment[] - if isnothing(gx[]) - gx[] = [ox+(i-1)*dx for i in range(start=1, stop=size(d[], 2))] + gx[] = [ox+(i-1)*dx for i in 1:size(d[], 2)] end traces = Observable(Vector{Point2f}[]) @@ -87,13 +85,21 @@ function Makie.plot!(wp::SeisWiggle{<:Tuple{AbstractMatrix{<:Real}}}) z = zeros(length(size(d, 1))) scale = wiggle_trace_increment*dgx*xcur/max_perturb - for i = 1:wiggle_trace_increment:length(gx) - trace = Point2.(gx[i] .+ (scale .* d[:, i]), times) - pos_trace = Point2.(gx[i] .+ max.(scale .* d[:, i], 0), times) - zero_line = Point2.(gx[i] .+ z, times) - push!(traces[], trace) - push!(positive_traces[], pos_trace) - push!(zero_lines[], zero_line) + st = gx[1] + for i = 1:length(gx) + while gx[i] >= st+wiggle_trace_increment*dgx + st += wiggle_trace_increment*dgx + end + + if gx[i] >= st && gx[i] < st+wiggle_trace_increment*dgx + trace = Point2.(gx[i] .+ (scale .* d[:, i]), times) + pos_trace = Point2.(gx[i] .+ max.(scale .* d[:, i], 0), times) + zero_line = Point2.(gx[i] .+ z, times) + push!(traces[], trace) + push!(positive_traces[], pos_trace) + push!(zero_lines[], zero_line) + st += wiggle_trace_increment*dgx + end end end diff --git a/src/SeisPlotTX.jl b/src/SeisPlotTX.jl index 5d0f138..d2a6f1b 100644 --- a/src/SeisPlotTX.jl +++ b/src/SeisPlotTX.jl @@ -59,7 +59,7 @@ function SeisPlotTX(d; elseif style == "wiggles" || style == "wiggle" if !isnothing(gx) ox = gx[1] - dx = minimum([gx[i]-gx[i-1] for i = 2:length(gx)]) + dx = wiggle_trace_increment*minimum([gx[i]-gx[i-1] for i = 2:length(gx)]) end seiswiggle!(ax, d; gx=gx, ox=ox, dx=dx, oy=oy, dy=dy, xcur=xcur, wiggle_trace_increment=wiggle_trace_increment,