|
| 1 | +include("colorscheme.jl") |
| 2 | +using PyPlot, DrWatson |
| 3 | +using3D() |
| 4 | +export rdspl, axis_zoomin!, add_identifiers!, nice_arrow!, figx, figy |
| 5 | + |
| 6 | +DrWatson._wsave(s, fig::Figure) = fig.savefig(s, dpi = 600, transparent = false) |
| 7 | + |
| 8 | +""" |
| 9 | + rdspl(x, n = 3) |
| 10 | +Round `x` with `n` sigdigits for display purposes. |
| 11 | +""" |
| 12 | +rdspl(x::Real, n = 3) = round(x, sigdigits=n) |
| 13 | +rdspl(x::AbstractVector, n = 3) = Tuple((round.(Float64.(x); sigdigits=n))) |
| 14 | + |
| 15 | +PyPlot.rc("lines", lw = 3) |
| 16 | +PyPlot.rc("errorbar", capsize = 6) |
| 17 | +PyPlot.rc("axes", grid = true) |
| 18 | +PyPlot.rc("grid", color = "0.75", alpha = 0.75) |
| 19 | +PyPlot.rc("axes", axisbelow=true) # makes grid behind other plotting elements |
| 20 | + |
| 21 | +MATHFONTSIZE = 34 |
| 22 | +PyPlot.rc("font", size = 28) # set default fontsize |
| 23 | +PyPlot.rc("xtick", labelsize = 24) |
| 24 | +PyPlot.rc("ytick", labelsize = 24) |
| 25 | +PyPlot.rc("axes", labelsize = MATHFONTSIZE) |
| 26 | +PyPlot.rc("legend", fontsize = 30, handlelength = 1) |
| 27 | +# PyPlot.rc("font", family = "Times New Roman") # Serif main font |
| 28 | +PyPlot.rc("font", family = "DejaVu Sans") # sans main font |
| 29 | +# PyPlot.rc("mathtext", rm = "sanserif", fontset="dejavusans") # sans math font |
| 30 | +PyPlot.rc("mathtext", rm = "serif", fontset="cm") # serif math font |
| 31 | + |
| 32 | +for z in ("x", "y") |
| 33 | + PyPlot.rc("$(z)tick.major", size = 7, width = 1.2) |
| 34 | + PyPlot.rc("$(z)tick.minor", size = 3, visible = false) |
| 35 | +end |
| 36 | + |
| 37 | +PyPlot.rc("figure", figsize = (figx, figy)) |
| 38 | +PyPlot.rc("savefig", dpi = 600, transparent = true, format = "png") |
| 39 | + |
| 40 | +# set default color cycle |
| 41 | +PyPlot.rc("axes", prop_cycle = matplotlib.cycler(color=COLORS)) |
| 42 | + |
| 43 | +if false # test font |
| 44 | + figure(figsize=(10,8)); plot(rand(10), label = "\$a=\\int_0^\\infty xdx\$") |
| 45 | + xlabel("x label"); ylabel("\$H_2\$"); legend(); tight_layout() |
| 46 | +end |
| 47 | + |
| 48 | +if false # test color scheme |
| 49 | + fig = figure(figsize = (20, 15)) # show colors |
| 50 | + ax1 = subplot(231) |
| 51 | + ax2 = subplot(232) |
| 52 | + ax3 = subplot(233) |
| 53 | + ax4 = subplot(223) |
| 54 | + ax5 = subplot(224) |
| 55 | + lw = 60 |
| 56 | + L = length(COLORSCHEME) |
| 57 | + for (i, c) in enumerate(COLORS) |
| 58 | + chsv = matplotlib.colors.rgb_to_hsv(matplotlib.colors.to_rgb(c)) |
| 59 | + ax1.plot([0, 1], [0, 0] .+ i, color = c, lw = lw) |
| 60 | + ax1.set_title("color") |
| 61 | + ax2.plot([0, 1], [0, 0] .+ i, color = string(chsv[3]), lw = lw) |
| 62 | + ax2.set_title("brightness") |
| 63 | + ax3.plot([0, 1], [0, 0] .+ i, color = string(chsv[2]), lw = lw) |
| 64 | + ax3.set_title("saturation") |
| 65 | + x = 0:0.05:5π |
| 66 | + ax4.plot(x, rand(1:3) .* cos.(x .+ i/2) .+ rand(length(x))/5; color=c, lw = 2) |
| 67 | + ax5.bar(collect(1:4) .+ (i-1)/L, 0.5rand(4) .+ 0.5, 1/L; color=c) |
| 68 | + end |
| 69 | + fig = tight_layout() |
| 70 | +end |
| 71 | + |
| 72 | +bbox = Dict(:boxstyle => "round,pad=0.3", :facecolor=>"white", :alpha => 1.0) |
| 73 | + |
| 74 | +"`add_identifiers!(fig = gcf(), axs = fig.get_axes(); xloc, yloc)`" |
| 75 | +function add_identifiers!(fig = gcf(), axs = fig.get_axes(); |
| 76 | + xloc = 0.975, yloc = 1 |
| 77 | + ) |
| 78 | + for (i, ax) in enumerate(axs) |
| 79 | + l = collect('a':'z')[i] |
| 80 | + if ax.name ≠ "3d" |
| 81 | + ax.text(xloc, yloc, "$(l)"; transform = ax.transAxes, |
| 82 | + bbox = bbox, zorder = 99, va = "top") |
| 83 | + end |
| 84 | + end |
| 85 | +end |
| 86 | + |
| 87 | +""" |
| 88 | + nice_arrow!(ax, xc, yc, xspan, yspan; |
| 89 | + style = "<->", tex = "", xo = 0.2, yo = -0.2, color = "C0" |
| 90 | + ) |
| 91 | +""" |
| 92 | +function nice_arrow!(ax, xc, yc, xspan, yspan; |
| 93 | + style = "<->", tex = "", xo = 0.2, yo = -0.2, color = "C0") |
| 94 | + |
| 95 | + ax.annotate(""; |
| 96 | + xy=(xc-xspan/2, yc - yspan/2), xycoords="data", |
| 97 | + xytext=(xc+xspan/2, yc + yspan/2), textcoords="data", |
| 98 | + arrowprops = Dict( |
| 99 | + :arrowstyle=>style, |
| 100 | + :connectionstyle=>"arc3", |
| 101 | + :lw=>1.5, :color => color), |
| 102 | + zorder = 99, color |
| 103 | + ) |
| 104 | + if tex != "" |
| 105 | + ax.text(xc + xo, yc + yo, tex; va = :center, color) |
| 106 | + end |
| 107 | +end |
| 108 | + |
| 109 | +""" |
| 110 | + axis_zoomin!(zoomin, origin, zbox, rbox, co = "C0"; kwargs...) |
| 111 | +Create a zoomin box connecting two axes, the `zoomin` and `origin`. |
| 112 | +The zoom-in box is in the `origin` axis, while the `zoomin` axis is the |
| 113 | +box. `rbox` is the enclosing box of the `zoomin` axes, while `zbox` |
| 114 | +is the small "zoom-in" box of the `origin` axis. They must be in the form |
| 115 | +((x1, y1), (x2, y2)). `co` is color `α` the alpha setting. |
| 116 | +""" |
| 117 | +function axis_zoomin!(zoomin, origin, zbox, rbox, co = "C0"; |
| 118 | + connect_lines = true, lw = 2.0, α = 1.0, dir = :right, set_lims::Bool=true) |
| 119 | + # plot box in zoomin axis |
| 120 | + line, = zoomin.plot( |
| 121 | + [rbox[1][1], rbox[2][1], rbox[2][1], rbox[1][1], rbox[1][1]], |
| 122 | + [rbox[1][2], rbox[1][2], rbox[2][2], rbox[2][2], rbox[1][2]], |
| 123 | + color=co, lw = lw, alpha = α |
| 124 | + ) |
| 125 | + line.set_clip_on(false) |
| 126 | + # plot box in origin axis |
| 127 | + line, = origin.plot( |
| 128 | + [zbox[1][1], zbox[2][1], zbox[2][1], zbox[1][1], zbox[1][1]], |
| 129 | + [zbox[1][2], zbox[1][2], zbox[2][2], zbox[2][2], zbox[1][2]], |
| 130 | + color=co, lw = lw, alpha = α |
| 131 | + ) |
| 132 | + line.set_clip_on(false) |
| 133 | + |
| 134 | + # xyA is zoomin axis, xyB is origin axis |
| 135 | + if connect_lines |
| 136 | + if dir == :right |
| 137 | + for e in 1:2 |
| 138 | + con = matplotlib.patches.ConnectionPatch( |
| 139 | + xyA = (rbox[1][1], rbox[e][2]), xyB=(zbox[2][1], zbox[e][2]), |
| 140 | + coordsA="data", coordsB="data", |
| 141 | + axesA = zoomin, axesB=origin, color=co, lw = lw, alpha = α) |
| 142 | + con.set_clip_on(false) |
| 143 | + zoomin.add_artist(con) |
| 144 | + end |
| 145 | + elseif dir == :top |
| 146 | + for e in 1:2 |
| 147 | + con = matplotlib.patches.ConnectionPatch( |
| 148 | + xyA = (rbox[e][1], rbox[1][2]), xyB=(zbox[e][1], zbox[2][2]), |
| 149 | + coordsA="data", coordsB="data", |
| 150 | + axesA = zoomin, axesB=origin, color=co, lw = lw, alpha = α) |
| 151 | + con.set_clip_on(false) |
| 152 | + zoomin.add_artist(con) |
| 153 | + end |
| 154 | + end |
| 155 | + end |
| 156 | + # Set limits for zoom axis |
| 157 | + if set_lims |
| 158 | + zoomin.set_xlim(zbox[1][1], zbox[2][1]) |
| 159 | + zoomin.set_ylim(zbox[1][2], zbox[2][2]) |
| 160 | + end |
| 161 | + # remove axis for zoomin |
| 162 | + zoomin.axis("off") |
| 163 | +end |
| 164 | + |
| 165 | +function darken_color(color, amount=0.5) |
| 166 | + c = matplotlib.colors.to_rgb(color) |
| 167 | + c = matplotlib.colors.rgb_to_hsv(c) |
| 168 | + c = (c[1], c[2], clamp(amount*c[3], 0, 1)) |
| 169 | + return matplotlib.colors.hsv_to_rgb(c) |
| 170 | +end |
| 171 | + |
0 commit comments