Skip to content

Instantly share code, notes, and snippets.

@tapyu
Last active June 27, 2026 01:57
Show Gist options
  • Select an option

  • Save tapyu/e9b5425621db4f0ee6c9ae7194d439e9 to your computer and use it in GitHub Desktop.

Select an option

Save tapyu/e9b5425621db4f0ee6c9ae7194d439e9 to your computer and use it in GitHub Desktop.
Julia PGFPlotsX

LaTeX-based plots using Julia's PGFPlotsX package

#!/usr/bin/env -S julia --project=@../../..
using HDF5
using PGFPlotsX
using JSON3
unitx_lib = raw"\usepackage{siunitx}"
if unitx_lib ∉ PGFPlotsX.CUSTOM_PREAMBLE
push!(PGFPlotsX.CUSTOM_PREAMBLE, unitx_lib)
end
units_lib = raw"\usepgfplotslibrary{units}"
if units_lib ∉ PGFPlotsX.CUSTOM_PREAMBLE
push!(PGFPlotsX.CUSTOM_PREAMBLE, units_lib)
end
spectrogram_settings = raw"\pgfplotsset{
/pgfplots/colormap={autumn}{rgb255=(255,0,0) rgb255=(255,255,0)},
/pgfplots/colormap={bled}{rgb255=(0,0,0) rgb255=(43,43,0) rgb255=(0,85,0) rgb255=(0,128,128) rgb255=(0,0,170) rgb255=(213,0,213) rgb255=(255,0,0)},
/pgfplots/colormap={bright}{rgb255=(0,0,0) rgb255=(78,3,100) rgb255=(2,74,255) rgb255=(255,21,181) rgb255=(255,113,26) rgb255=(147,213,114) rgb255=(230,255,0) rgb255=(255,255,255)},
/pgfplots/colormap={bone}{[1cm]rgb255(0cm)=(0,0,0) rgb255(3cm)=(84,84,116) rgb255(6cm)=(167,199,199) rgb255(8cm)=(255,255,255)},
/pgfplots/colormap={cold}{rgb255=(0,0,0) rgb255=(0,0,255) rgb255=(0,255,255) rgb255=(255,255,255)},
/pgfplots/colormap={copper}{[1cm]rgb255(0cm)=(0,0,0) rgb255(4cm)=(255,159,101) rgb255(5cm)=(255,199,127)},
/pgfplots/colormap={copper2}{rgb255=(0,0,0) rgb255=(68,62,63) rgb255=(170,112,95) rgb255=(207,194,138) rgb255=(255,255,255)},
/pgfplots/colormap={earth}{rgb255=(0,0,0) rgb255=(0,28,15) rgb255=(42,39,6) rgb255=(28,73,33) rgb255=(67,85,24) rgb255=(68,112,46) rgb255=(81,129,83) rgb255=(124,137,87) rgb255=(153,147,122) rgb255=(145,173,164) rgb255=(144,202,180) rgb255=(171,220,177) rgb255=(218,229,168) rgb255=(255,235,199) rgb255=(255,255,255)},
/pgfplots/colormap={hot2}{[1cm]rgb255(0cm)=(0,0,0) rgb255(3cm)=(255,0,0) rgb255(6cm)=(255,255,0) rgb255(8cm)=(255,255,255)},
/pgfplots/colormap={hsv}{rgb255=(255,0,0) rgb255=(255,255,0) rgb255=(0,255,0) rgb255=(0,255,255) rgb255=(0,0,255) rgb255=(255,0,255) rgb255=(255,0,0)},
/pgfplots/colormap={hsv2}{rgb255=(0,0,0) rgb255=(128,0,128) rgb255=(0,0,230) rgb255=(0,255,255) rgb255=(0,255,0) rgb255=(255,255,0) rgb255=(255,0,0)},
/pgfplots/colormap={jet}{rgb255(0cm)=(0,0,128) rgb255(1cm)=(0,0,255) rgb255(3cm)=(0,255,255) rgb255(5cm)=(255,255,0) rgb255(7cm)=(255,0,0) rgb255(8cm)=(128,0,0)},
/pgfplots/colormap={pastel}{rgb255=(0,0,0) rgb255=(120,0,5) rgb255=(0,91,172) rgb255=(215,35,217) rgb255=(120,172,78) rgb255=(255,176,24) rgb255=(230,255,0) rgb255=(255,255,255)},
/pgfplots/colormap={pink}{rgb255=(0,0,0) rgb255=(12,16,46) rgb255=(62,22,43) rgb255=(53,53,65) rgb255=(79,72,58) rgb255=(122,80,67) rgb255=(147,91,102) rgb255=(147,115,140) rgb255=(144,145,154) rgb255=(173,163,146) rgb255=(216,171,149) rgb255=(250,179,179) rgb255=(255,198,227) rgb255=(246,229,255) rgb255=(255,255,255)},
/pgfplots/colormap={sepia}{rgb255(0cm)=(0,0,0) rgb255(1cm)=(26,13,0) rgb255(18cm)=(255,230,204) rgb255(20cm)=(255,255,255)},
/pgfplots/colormap={spring}{rgb255=(255,0,255) rgb255=(255,255,0)},
/pgfplots/colormap={summer}{rgb255=(0,128,102) rgb255=(255,255,102)},
/pgfplots/colormap={temp}{rgb255=(36,0,217) rgb255=(25,29,247) rgb255=(41,87,255) rgb255=(61,135,255) rgb255=(87,176,255) rgb255=(117,211,255) rgb255=(153,235,255) rgb255=(189,249,255) rgb255=(235,255,255) rgb255=(255,255,235) rgb255=(255,242,189) rgb255=(255,214,153) rgb255=(255,172,117) rgb255=(255,120,87) rgb255=(255,61,61) rgb255=(247,40,54) rgb255=(217,22,48) rgb255=(166,0,33)},
/pgfplots/colormap={thermal}{rgb255=(0,0,0) rgb255=(77,0,179) rgb255=(255,51,0) rgb255=(255,255,0) rgb255=(255,255,255)},
/pgfplots/colormap={winter}{rgb255=(0,0,255) rgb255=(0,255,128)},
/pgfplots/colormap={inferno}{%
rgb=(0.001462, 0.000466, 0.013866)
rgb=(0.037668, 0.025921, 0.132232)
rgb=(0.116656, 0.047574, 0.272321)
rgb=(0.217949, 0.036615, 0.383522)
rgb=(0.316282, 0.053490, 0.425116)
rgb=(0.410113, 0.087896, 0.433098)
rgb=(0.503493, 0.121575, 0.423356)
rgb=(0.596940, 0.154848, 0.398125)
rgb=(0.688653, 0.192239, 0.357603)
rgb=(0.775059, 0.239667, 0.303526)
rgb=(0.851384, 0.302260, 0.239636)
rgb=(0.912966, 0.381636, 0.169755)
rgb=(0.956852, 0.475356, 0.094695)
rgb=(0.981895, 0.579392, 0.026250)
rgb=(0.987464, 0.690366, 0.079990)
rgb=(0.973088, 0.805409, 0.216877)
rgb=(0.947594, 0.917399, 0.410665)
rgb=(0.988362, 0.998364, 0.644924)
},
compat=1.13,
% unit markings=parenthesis,
unit code/.code 2 args={\unit{#1#2}},
}
\sisetup{per-mode=symbol}"
if spectrogram_settings ∉ PGFPlotsX.CUSTOM_PREAMBLE
push!(PGFPlotsX.CUSTOM_PREAMBLE, spectrogram_settings)
end
# push!(PGFPlotsX.CUSTOM_PREAMBLE, spectrogram_settings)
# load HDF5 file and settings
h5_path = joinpath(dirname(Base.active_project()), "reports", "example_idx2_val.h5")
spectrogram, spectrogram_attrs, emitters_data_json = h5open(h5_path, "r") do file
dset = file["spectrogram"]
spectrogram = read(dset)
dset_attrs = attrs(dset)
spectrogram_attrs = Dict(name => dset_attrs[name] for name in keys(dset_attrs))
emitters_data_json = JSON3.read(read(file["emitters_data_json"]))
spectrogram, spectrogram_attrs, emitters_data_json
end
## Overall settings for plotting
tile_scale = 1.5
# create new axis
axis = @pgf Axis(
{
"colormap name" => "inferno", # NOTE: you can switch to "colormap/jet"
axis_on_top,
use_units,
width = "$(tile_scale * 6.2)cm",
height = "$(tile_scale * 4.1)cm",
ylabel = raw"Time",
"y unit" => raw"\milli\second",
y_dir= raw"reverse", # NOTE: this is important to have time increasing downwards
xlabel = raw"Frequency",
"x unit" => raw"\mega\hertz",
title = "Spectrogram",
"enlarge x limits" => false,
"enlarge y limits" => false,
colorbar,
"colorbar style" => {
ylabel = raw"PSD",
"y unit" => raw"\decibel\per\hertz",
},
},
)
# plot spectrogram
plot = @pgf Plot(
{
"point meta min" => minimum(spectrogram),
"point meta max" => maximum(spectrogram),
},
Graphics(
{
xmin=spectrogram_attrs["rf_min"]/1e6,
xmax=spectrogram_attrs["rf_max"]/1e6,
ymin=0,
ymax=spectrogram_attrs["ex_duration"]/1e-3,
},
"spectrogram_bare.pdf"
)
)
push!(axis, plot)
# plot ground truth emitter bboxes
for emitter in emitters_data_json
rf_start_mhz = emitter["rf_start_hz"]/1e6
rf_stop_mhz = rf_start_mhz + emitter["bw_hz"]/1e6
start_time_ms = emitter["start_time_s"]/1e-3
stop_time_ms = start_time_ms + emitter["duration_time_s"]/1e-3
rect = @pgf Plot(
{
"draw" => "green",
"fill" => "none",
"line width" => "1.0pt",
dashed = "2pt 2pt",
},
Coordinates(
[
(rf_start_mhz, start_time_ms),
(rf_stop_mhz, start_time_ms),
(rf_stop_mhz, stop_time_ms),
(rf_start_mhz, stop_time_ms),
(rf_start_mhz, start_time_ms),
]
)
)
push!(axis, rect)
end
# create Tikz picture
@pgf tp = TikzPicture({},
axis,
# raw"\node[above=1em,xshift=7em, font=\LARGE] at (current bounding box.north) {Carrier phase estimation under scintillation};",
)
# create document and save to file
doc = TikzDocument(tp)
out_file = joinpath(dirname(Base.active_project()), "reports", "spectrogram_examples", "idx1_trn", "main.tex")
PGFPlotsX.save(out_file, tp; include_preamble=true)
@info "Saved PGFPlotsX figure" path=out_file
View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment