From 43e6beb90f075e12b5b07a1e08a38e54471fd463 Mon Sep 17 00:00:00 2001 From: Chris Tessum Date: Thu, 8 Mar 2018 14:13:14 -0800 Subject: [PATCH] Respond to comments --- plotter/colorbar_test.go | 7 +++++- plotter/image.go | 23 ++++++++++-------- plotter/image_test.go | 2 +- .../testdata/colorBarHorizontalLog_golden.png | Bin 2515 -> 2214 bytes plotter/testdata/image_plot_log_golden.png | Bin 6783 -> 6893 bytes 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/plotter/colorbar_test.go b/plotter/colorbar_test.go index f2c11437..37892b56 100644 --- a/plotter/colorbar_test.go +++ b/plotter/colorbar_test.go @@ -5,6 +5,7 @@ package plotter import ( + "image/color" "log" "testing" @@ -41,7 +42,11 @@ func ExampleColorBar_horizontal_log() { if err != nil { log.Panic(err) } - l := &ColorBar{ColorMap: moreland.ExtendedBlackBody()} + colorMap, err := moreland.NewLuminance([]color.Color{color.Black, color.White}) + if err != nil { + log.Panic(err) + } + l := &ColorBar{ColorMap: colorMap} l.ColorMap.SetMin(1) l.ColorMap.SetMax(100) p.Add(l) diff --git a/plotter/image.go b/plotter/image.go index cd154d61..86b36fb2 100644 --- a/plotter/image.go +++ b/plotter/image.go @@ -56,7 +56,7 @@ func (img *Image) Plot(c draw.Canvas, p *plot.Plot) { Min: vg.Point{X: xmin, Y: ymin}, Max: vg.Point{X: xmax, Y: ymax}, } - c.DrawImage(rect, img.transform(p)) + c.DrawImage(rect, img.transformFor(p)) } // DataRange implements the DataRange method @@ -72,7 +72,7 @@ func (img *Image) GlyphBoxes(plt *plot.Plot) []plot.GlyphBox { } // transform warps the image to align with non-linear axes. -func (img *Image) transform(p *plot.Plot) image.Image { +func (img *Image) transformFor(p *plot.Plot) image.Image { _, xLinear := p.X.Scale.(plot.LinearScale) _, yLinear := p.Y.Scale.(plot.LinearScale) if xLinear && yLinear { @@ -81,21 +81,24 @@ func (img *Image) transform(p *plot.Plot) image.Image { b := img.img.Bounds() o := image.NewNRGBA64(b) for c := 0; c < img.cols; c++ { + // Find the equivalent image column after applying axis transforms. + cTrans := int(p.X.Norm(img.x(c)) * float64(img.cols)) + // Find the equivalent column of the previous image column after applying + // axis transforms. + cPrevTrans := int(p.X.Norm(img.x(maxInt(c-1, 0))) * float64(img.cols)) for r := 0; r < img.rows; r++ { - // Find the equivalent image row and column after applying - // the axis transforms. - cTrans := int(p.X.Norm(img.x(c)) * float64(img.cols)) + // Find the equivalent image row after applying axis transforms. rTrans := int(p.Y.Norm(img.y(r)) * float64(img.rows)) - // Find the equivalent row and column of the previous image row - // and column after applying the axis transforms. - cPrevTrans := int(p.X.Norm(img.x(maxInt(c-1, 0))) * float64(img.cols)) + // Find the equivalent row of the previous image row after applying + // axis transforms. rPrevTrans := int(p.Y.Norm(img.y(maxInt(r-1, 0))) * float64(img.rows)) - crColor := img.img.At(c, r) + crColor := img.img.At(c, img.rows-r-1) // Set all the pixels in the new image between (cPrevTrans, rPrevTrans) // and (cTrans, rTrans) to the color at (c,r) in the original image. + // TODO: Improve interpolation. for cPrime := cPrevTrans; cPrime <= cTrans; cPrime++ { for rPrime := rPrevTrans; rPrime <= rTrans; rPrime++ { - o.Set(cPrime, rPrime, crColor) + o.Set(cPrime, img.rows-rPrime-1, crColor) } } } diff --git a/plotter/image_test.go b/plotter/image_test.go index dc4a8b84..f89a6b9e 100644 --- a/plotter/image_test.go +++ b/plotter/image_test.go @@ -63,7 +63,7 @@ func ExampleImage_log() { p.Title.Text = "A Logo" // load an image - f, err := os.Open("testdata/image_plot_input.png") + f, err := os.Open("../../gonum/gopher.png") if err != nil { log.Fatalf("error opening image file: %v\n", err) } diff --git a/plotter/testdata/colorBarHorizontalLog_golden.png b/plotter/testdata/colorBarHorizontalLog_golden.png index 6a7f37492405ff425da57f3002744aa284be29bc..9df45360da4046f5fe04c7ac85ae5bebd042ddb5 100644 GIT binary patch literal 2214 zcmb_eX*Ap09t|ELhAN8EJT+ZfO2sX%sa~!WH8r7xpiyFKOjm9H9Qd&by5ySnju65s9@B2F+_BtQVI%ofey?-a~oQIP zf#hAB9Z?{V*ll3%AT16ct)vA&>1Y?ne|aZYEOG*!iaA z7J$JaUC~2~GVbiYNTzR=&}BO@zp={hyk6*nR1pJJOIZ3EfIu^bD#oB{`5!>0D1$z3 z*$js%6W^?^u6~GWe)Z~=sym0n!QpUA(_N+}CJGS9wn6#p_BY*R8>{(ucZ}B8*Tuxd zZ2!45M)9?-{Qj1to6>nDG&K9o#ksk;fzapM+uK`P$;4~N@0>lV__DQiX_CrBQ0dm! zjEv(l;SZNLHx06%kjV;ia+6&dRf=%r=s>XnLI>&Ml7}|7*uY0buwF)bd3%>oymASW zspy%f1qE`aPoG|}%IbMLFcAEL%^Ru|tgZblC0JdR0)xN3Co}mzC%n+D=Nh|_N_p8m zSQcK1_$DVOXKHGSKp5QZTLq= zhwbs>?-0YF2pM1Wvgg>?*h+E-)Fx38o(=yGZ@B9G@jH}a@sB{_cD$Zl==v$U!Y*|@ znNU?!^k^*VS2#SNQf)*6qPpW192^`J6m&q#{xU(w!8O@M+Gx1VGWMi;{e2~6Wsyj9 zN~6$dRs19Ukg8R9OpHf^&#hax_IE|CG@6Z-6^l;KQe0h_FonNmvD6VrV^t$#axl5Jx`E0|+rxQ?VA zLlYAZJtcX0`LWSab=`|i=;L>;Y_HWle-5*OHy5+43TRpYaB zc(@3?**YDS0T+cQEqBNgUf8#s?)}`|)3*LtxL?9>a?0d_$KAR0G{2;{gaq@`7K!GP z4EBL`#)}*G!S4OCQ1lTRb$B0hS7a;DVraQHd{@B2%E|qRjI#I~Nzlt{ng3r1evEZ@ zcch7Ekh!g`?JvI^R#N)B z=urD$w*Quvq`261x*xY9IyxGOL~2^#;}VmBwoFNB&tkWio_SneSve;VQc_BRo^U*K zCT6lNzFhFLrKM~RJSi!u_RL|q+|p9jCiEh9pG+pRSS$n&9}`pRte3dW^3(S6@~W(? zG&3_BcbAZm02=+e0@Ob)=-pW?wwe&fuufTvkKqFY14zo)V3mQndBVkuui41r;^Oe3 ziujKGmDzr1xnQ);YeNK3h-$VrFz63s0>K&?8GUmj+Wpsaei)DDwCg;N$IEvsbv7w` zwsCA{cNd}a?^T|Rf&zCX`3IMhflxrdgH?i=o-DjYstkR1cUKMIa!^C#kBJ3ek@3pP zN`Og{P;kUPE&1W5!y-`fyu7@do1PvXiJ?PJp6H3v7wZ*G$~3jKmXgnM@g1&rNu-rE zKC{Lh9QV05FFzmR8!qQ zhQ0VU{Vq0y2?b%JU%SHpw$V?Lml6{j6!wZ_WI$}TJ{@VMNK@0>xN zpa#WXUziZ4?KNOp+i5gqB_+Vg_Y!jSRUn>K_MP+LU1E3RsFRC}i;ayZ1=Xm!$>vLH z+M%CXqBRQpcAgo6w7;;LLS$rQxCd)choMjg_T*i+u*;V(hlD&9!XXC^XhEU7d%HFk zoZuY(`gTi;#VnWtQ!luETM>Br>l19lrKl)ax_WFx#8XsVMR|E-WTcs-r1&*donuet zAqzl6c6QP2yR3-`-x?Iv`WSj)TO>L$Uf@Hiym#-p^doE!WL6-wx3|yA%Ieb+ZEyR0 zq5qCeC+6juHIxGmPI6XJRBXfzsuGVvRO?SlWoeU~fg1`pt#`Io=qs@fSNAc1YWq(8 zDh4f9ckD!{=+duhe)i2c1?K*e-AJv}`g z3WdVT3lxh=O4fFS30Xbo0s~KwoUM-B6cuV(x`p^-FoT1Gr!*M7z1e4L@^9SeMoEbJ z`ukm7T`?F;ZEY=BN{WTw7;nJfVCA*7yh@v-wtyHUl5}5l&*XK6p-O)E@Pos0Qr|j& z`NOzxSzA+cNKLJ^rDckiG`z*R6dxZCjOFhf+7X4?r%&HaRO|~Zve<&WMg6G8eKx0^|4nXAMtKQ_`kZ}a`6uzaAwOY95d@?(Ww2K zc;)Lb{$hXKbGo-+MX&qSdqO#4lbq~Z6-Nax$aD(_+AG+8IQ_u_l7H^>MPp?v?dzZN^Y26lH}Qe>1su zbab@Yezd_&7UAVa`kKkoBICTgWE2<2D(oaBCFLI-C@Lmj+S?g-JeS>5R3wwvuRKUw zS<#E#33PXN$J(WG@k|mF+*49gdY{TopT*_>k)QwC_3asC^upFcw=wwN;#IX61$*h@BGa$UFm;5lS8D8yFB!d|6*#aH)YrvgTtRuGLhO1L1IMG}`nw zZ63{bQ#;MY#g$cicz9S-M&^m(bS|5@1xN)6&Gn!L>?X<48$jvxrA{n(OU>_LdMfS z4hEZWCU+XnDw>#^n~%kvQEqB#`t?OvP|(|o3d@XV_9~el8K0mXFddy&I9&1IGSE_l zOzcYelb4^?m6Vjq9_|%7zj-%>ikgcFNEG2&U)6&3j}l*7-G*V&a47ga+WV6L3p)Otydh;`8x4xLTD>n zb%}3@f9WTjLMz%B9kkj>&!X_FTE6^kK<{p`AnL00vu?cswc%*QOIb>EF2!=Lqq9#@ zMJ1PP?sv^HUj3WPzrZ}#r21?n=s%}H(+`s0r(TISy0&m^ZgO%s4o>i<@W|I}g(c>k ziFd924mD06QSRbT!1BPQvKYG0Q&HRvEc26YK5qTzKBmj>bFV%ZOAzO|4G&EcPpDPy zIe4E6_Y>%e9_>*4MJ3I?R+7?ChZ;cGlV zGy0QVnD=I7k-i*{QGfoQVG-zQXJ?oGnj3UeP`n+pH5a$}@M{9EgsbC>fuZ4M%VxW= z&#mC#V1NJRoz-!}&sxUDZ6wmO++6X^r(trGVN-V1S0rL@cNb6y7!3Z{66fMF zUZCM|t4gPKCV2n*_qPb#^tjuj!&MwHVEDYj{lF(N%`Gj$r?`fD_iHIwwY{C4XZEko zQllO`SXx{}6%t!orcpXpg_27`*8t(j${Iy&%=DC}r>BpNjai+K@f&YNB}u9xP(mBm zb4*VTkWhNJsA=obMvLL__+Ni{xwsIsjSRO$cN!+GzR_vaOjw5Zgp%W@Zi>?|aj>%i6i>$7La$Hp4GAC~Do_?|yZonCWeFc>hI!J%!V!<84svs~$L zvE<|9<1f@3q)^2_N`Te>Pbx4O2P6_n1E*w!Vh9An7T~0Lq`_m{^VqlL<%*+jk2SSn zFuugAo}Q#B?qfSXP+dYQ&p!}fz#io)SxGqY%Zk-{GkDXiE1WIS8tCNA4G`!^@&wHN zPf=+z1a}XQkXW!n$hqOdf`S5WGAD!3&>$@>ZW(s_mmLd%5Kk711z4=UzCO-fSr)dv zy zoJZ+Q%cGBTM`V2G@1juu4yuP>G|n z7Z(TAr>dgjs!j$P7hLZpDsOTOnC335=l@K^u< diff --git a/plotter/testdata/image_plot_log_golden.png b/plotter/testdata/image_plot_log_golden.png index 4458bc51e576ea68eb5f863897c9410a39e8a3a9..56686b53568a09d0e1d966a6b57670bd18422124 100644 GIT binary patch literal 6893 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 SK7+5ZAX<0z)GJgiLjMOwSdsPs literal 6783 zcma)>cT`hdm&PMVk&g7Bf*?hti}Wrc0tN&`N(j|R@4ZV$jHrl!lz@nclz@@m3B8Db zNbf=jz4tQ5_nmL8Su_6(3&JAY+JQXZ41Cj8(j5%+pFsD0RE2Lmr)yHkd>$&L9P#2gg}`J$3HH}gzwz&{ zSC?&{EZY{o!kEEQN@Zb6Mk3kSzh#-$ooYW8RhiIH8=}4_8z|FTQzc1U)X*TRe3Rxw zeQbtTV9?Wi^+&ZT1icqLEORW=f%e#&9|;%`r6MMeNYxEmg;;5Xd4_Wm_fv;aNtnw` zyS>xo32%%+p}Y>CBy`x67+J{j^Ycqc{HmU$eoS=YH!wQ-AuUaiIqoV=bQh7&`lMO4 zx0A2$!O`xrhkSnx$p7p;3dp<4R5&b|3E8=T#hX=uNO|} zaGt7rn5BDklf(Al=s8}c%z46pzLSXx_x0;n2qc=8!`rw3z5foDn>|1fPoctz#wA6$eQsK9aRGKG_R}R)meD|(9S&SI+IweKMdu15hg%4(9 zE?&u9I_>34DhMRJvAwG++zFp5<+8MU^!>X8MA_3*0^J+3v-s%mDMAN(3QfyLM@JWa zq|4>9K$QLb4!7~W6IB{^c6Rpm0vT7OoYT~}N{j>v1cHi+O1bj{5kx{lf)&*Yj@#D{ z)?M!wAs^oB*_>;mbljtS{%<;_s`g6G4ItYsl7mhYpVJ5$FpH9SjZM<7POa z9`5dHT#u%jg2tpKCMM#Tg_=ZHW^mDr6!$PgcaLlQwtr*H<1LdB7?!vefy7RN9@w)D z@&-I=#8J_0wt2BH8>P;zcs4dMp73aL_WVx{15QC_-8~A+dNfFpu&#w1EkkHScKX-O^f+sf*10l**Rwg7y(Pi9F)MMX&o{pWjJee5nZ7Y2rk%<}W{2mx<)c6P$T zh>{KY8K;8w&0w$}?{4Z_JY$D!;FZp0goTBrrCA}INnNy8WqzoIaF3v}%*+ ze*Cps|J@}}Sr)&Y%iEfpuPFF4CRsNygs$Hd3AG%KV-c|!b(CD6s7~sdhowsP3eF37D#Z}4kKk&AOqaJGkn9>kpw z^`O|L(vZ_%^Ybk)6469ivWOrYU0nE}Ub1FxZYBDh3%F?7^{M)Gv2uFFD2lmM!vZ5Q zzb%{aMo1xP_{{14RDH;Kof?;MiB)8u?M29VeMm^hTOPQu&s-}C^kgK@KG+AZWkZ_i z+aYHs)jsP)keBLnON03?``-bT~>f6f!X}#m2^p zrY9%!Cu*7ptd_ob@q$+I00L>SDhUe@cW`jH0LjYAa;2bS_Bb?#OF20?DV?8qC{3=6 zVDZhd4A-iSrCg=2n3%~kYjd)P~oUZ!w2o3in6*_!UdUeR?#$9o0O{E=R1SH zp8rYEi5UT#O+8t7UB3OCy}r-B)b$1_l9Gbri@_3*hO=$-d9hJJECXMYM$SO4PM6I$ zujSuP;}vf-b4W=@PSJ?9iE5vvUwQkJ0kjZNP+!b(UPn6w?)$HF^9E{XPC&jhsIUxaZ3NChm10yNe=}kVi z>nF?{%cScicXf}EUqVO!yVa)W_8Fn|Y#+fn%>&@w!wNXRwnX89^(qvtVWB2#q4;n0voR{ zizw&l*-1dDZZ!;KeC_f`Qoktrx4jPz6m}2sXa+2QOwgBU>xt>UFLb$2rO4}B+NwIb zyKf)~o>l9CDis&(r~cJ}f4o@Hd5WKr!U`zP@sFhQ#u?XSZC?2<8}YlUs>64B%xJTysKNR2-Vv6a|cSx z%jK@nRG=y2+rs%`hgbKaqDUoE6&!~}F^7&NMvN3BiJGg=TrwJo2(5QOSK(%+jpJIZ zL|Kpa9NEDa6w1ZLWf5qouHFhvZD!&4cz+!<;lY?o{pua`9cT|IDT1eLT+7yuHagx5 zYtcw#Rffe5_|$QZH?&nfHzl9V+)T|PvS;D`M_P&PS*m%ZrG1-Y=zYs7S+2z=y?xtX z4(vW`?;XO##Khm<|1twZq-s{z*0nHL?(G!qYw>MXB{AtLI-#C(P@3q3#Kg#Fy%`E) z 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 c1af}vvx+e9`pzK$K3IZ0xCc`!Qnd*CFN