Here's some work I've done creating palettes for plots.
NB.* bmpPal.ijs: bitmap and palette-generation fns.
NB.* makeGrayPal: make gray palette with y entries from black to white.
NB.* brightnessAdjust: adjust palette brightness so gray-scale monotonic dark->light.
NB.* InterpPts: interpolate x points between each point in 3-col mat y .
NB.* InterpPtPairs: interpolate x points given 2-row mat of y=. Point Pairs.
NB.* buildFullSpectrumPalette: make palette with pleasing, full range of colors.
NB.* FULLSPECPAL: black->dark blue->green->cyan->purple->red->orange->yellow->almost white
NB.* adjustFullSpectrumPalette: make full-spectrum palette better...
NB.* ADJPAL: black->dark blue->green->greyish->purple->red->orange->yellow->almost white
NB.* GRAYPAL: black->shades of gray->white
NB.* BGYPALn: Blue->Green->Yellow palettes (hand-tweaked)
NB.* pwlin: piecewise linear function
NB.* getLetter: get letter in bitmap file and fit within bounds of numeric
NB.* blendLettWMat: blend boolean letter mat with numeric mat.
NB.* layLettOnMat: lay boolean letter mat on top of numeric mat.
NB.* layLettOnMat: lay boolean letter mat on top of numeric mat.
NB.* encimage64: encode image file into 64 (printable) character format.
NB.* unencimage64: convert 64 character format->original array.
NB.* roundNums: round numbers y to precision x, e.g.
NB. load 'plot viewmat'
NB. ADDONS_j_=: >(1{"1 SYSTEMFOLDERS_j_){~(0{"1 SYSTEMFOLDERS_j_)i. <'addons'
NB. load 'jzplot'
NB.* makeGrayPal: make gray palette with y entries from black to white.
makeGrayPal=: 13 : '|:3#,:<.0.5+(255%<:y)*i.y'
ChangeViewmatPalette=: 0 : 0
BANDCOLOR=: ADJPAL
NB. or
ADJPAL viewmat i. 16 16
)
ChangePlotPalette=: 3 : 0
RGCLR_jwplot_=: ADJPAL
NB. STDCLR_jzplot_=: }.}: makeGrayPal 5
NB. STDCLR_jwplot_=: ADJPAL
)
NB.* brightnessAdjust: adjust palette brightness so gray-scale monotonic dark->light.
brightnessAdjust=: 3 : 0
diffs=. (+/|:y)-~(256%~>./+/|:y)*i.256
|:roundNums 0 255 scaleNums (|:y)+"1 diffs%3
)
sombrero=: 13 : '(]%~1 o.])([:%:&>[:+/&.>*:&.>)(,&.>/~)y'
sombrero=: 13 : '(1&o.%])%:+/~*:y'
NB.EG 'surface' plot sombrero i:20j99
dyasombrero=: (4 : '(1&o. % ]) %:+/*:x,y')"0/
NB.EG plot _20 20 100; _20 20 100; 'dyasombrero'
cyl=: 3 : '(r<:d%2)*(0.5*r=d%2)+(r>:0)*.r<d%2 [ ''d r''=. y'
saveBMPFl=: 3 : 0
savemat_jviewmat_ y
NB.EG 'surface' plot +/~ 1 o. 0.1*i.100
NB.EG saveBMPFl 'bumpyPlot.bmp'
NB.EG viewmat j./~i:10 NB. complex plane
NB.EG saveBMPFl 'swirlyComplexPlane.bmp'
)
skew=: 3 : 0
(i.#y)|."0 1 y
)
MYPLOT=: 0 : 0
pc myplot closeok;
xywh 2 2 800 800;cc g0 isigraph ws_border rightscale bottommove;
xywh 131 3 34 11;cc close button leftmove rightmove;cn "Close";
pas 2 2;pcenter;
rem form end;
)
myplot_close_button=: wd bind 'pclose'
NB. wd MYPLOT
NB. a=: conew 'jzplot' NB. create plot object
NB. PForm__a=: 'myplot' NB. define PForm in a
NB. PFormhwnd__a=: wd 'qhwndp' NB. define PFormhwnd in a
NB. PId__a=: 'g0' NB. define PId in a
NB. PId__a1=: 'g0' [ PFormhwnd__a1=: wd 'qhwndp' [ PForm__a1=: 'myplot'[a1=: conew 'jzplot' [ wd MYPLOT
NB. 'density' plot__a 7|i.25 25 NB. draw plot on the form
defineColorCubeGlobals=: 3 : 0
CORNERS=: 0 4 2 1 6 5 3 7 {255*2 2 2#:i.8
AllZ2Zs=: 0 1 2 4 3 6 5 7;0 1 2 4 3 5 6 7;0 1 3 5 2 4 6 7;0 1 3 5 2 6 4 7;0 2 1 4 3 6 5 7;0 2 1 4 3 5 6 7
AllZ2Zs=: >AllZ2Zs, 0 2 3 6 1 4 5 7; 0 2 3 6 1 5 4 7; 0 3 1 5 2 4 6 7; 0 3 1 5 2 6 4 7; 0 3 2 6 1 4 5 7; 0 3 2 6 1 5 4 7
transitionMat=: 7 8$0 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 1 0 1 1 0 1 0 0 1 1 0 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 1 0 1 1 0 0 0 0 1 1 0 1
)
defineColorCubeGlobals ''
InterpPts=: 4 : 0
NB.* InterpPts: interpolate x points between each point in 3-col mat y .
y=. }.}:2#y
y=. ((#y)$1 0)<;.1 y
x InterpPtPairs&.>y
)
InterpPtPairs=: 4 : 0
NB.* InterpPtPairs: interpolate x points given 2-row mat of y=. Point Pairs.
diffs=. --/pp=. y
steps=. diffs%>:np=. x
ip=. (0{pp)(+"1 1)steps(*"1 0)i. np
)
NB.* buildFullSpectrumPalette: make palette with pleasing, full range of colors.
buildFullSpectrumPalette=: 3 : 0
pal11_38_base_=: 256{.1 roundNums >,&.>/38 InterpPts (11{AllZ2Zs){CORNERS
NB. pal12_38=. (<<<124+i. 10){pal12_38
NB.* FULLSPECPAL: black->dark blue->green->cyan->purple->red->orange->yellow->almost white
FULLSPECPAL=: 256{. roundNums >,&.>/24 36 46 40 40 50 30 InterpPts (0 3 2 6 5 1 4 7){CORNERS
)
buildFullSpectrumPalette ''
NB.* adjustFullSpectrumPalette: make full-spectrum palette better...
adjustFullSpectrumPalette=: 3 : 0
len=. #ix=. 80+i.56 NB. Adjust the mid-palette to elim
NB. ((<:<./ix),>:>./ix){FULLSPECPAL NB. cyan because it's too light at
NB. 0 255 103 NB. transition and too similar to
NB. 187 68 255 NB. blue at low end of palette.
pb=. |:FULLSPECPAL{~({.,{:) ix NB. Patch borders
patch=. stepsftn"1]pb,.len NB. Linear-match RGB each to within 2
bv=. -:|.(]%~[:>:i.)len NB. Blend-vec: push patch toward gray,
patch=. |:roundNums (>:bv)%"1~patch+"1 bv*128 NB. strongly->weakly
ADJPAL=: patch ix}FULLSPECPAL
)
adjustFullSpectrumPalette ''
NB.* GRAYPAL: black->shades of gray->white
GRAYPAL=: |:3 256$i.256
NB.* BGYPAL: Blue->Green->Yellow palettes (hand-done)
NB. These palettes keep down the number of different colors to reduce
NB. the "busyness" of a graph. Also, they vary smoothly from dark to
NB. light so will stay distinct when printing in black & white.
BGYPAL=: ;stepsftn&.>0 0 86;64 127 85;120 200 43;220 255 42 NB. Red,
BGYPAL=: BGYPAL,:;stepsftn&.>0 80 85;96 224 86;230 255 85 NB. Green,
BGYPAL=: BGYPAL,;stepsftn&.>0 255 75;250 112 95;64 128 86 NB. Blue
BGYPAL=: roundNums |:BGYPAL
BGYPAL2=: ;stepsftn&.>0 60 30;62 80 30;80 100 26;102 140 85;142 210 43;220 255 42
BGYPAL2=: BGYPAL2,:;stepsftn&.>0 100 55;102 140 30;142 224 86;228 255 85
BGYPAL2=: BGYPAL2,;stepsftn&.>0 255 45;250 88 100;64 130 60;132 200 51
BGYPAL2=: roundNums |:BGYPAL2
BGYPAL3=: ;stepsftn&.>0 60 30;62 80 30;80 100 26;102 140 85;142 210 43;220 255 42
BGYPAL3=: BGYPAL3,:;stepsftn&.>0 100 55;102 140 30;142 224 86;228 255 85
BGYPAL3=: BGYPAL3,;stepsftn&.>0 255 45;250 88 116;86 130 44;132 200 51
BGYPAL3=: roundNums |:BGYPAL3
writebmp8=: 3 : 0
:
NB. write 8-bit uncompressed *.bmp files
('spal';'sbmp')=.$@>"0 x
xsbmp=.sbmp+(i.2)*4|-sbmp
h=.524289 0,(*/xsbmp),0 0,2#spal=.0{spal
h=.(54+(4*spal)+*/xsbmp),0,(54+4*spal),40,(|.sbmp),h
head=. 'BM',,a.{~,|."1 (4#256)#:h
pal=. ,(0,"1~|."1 >{.x){a.
bmp=. ,|.(xsbmp{.>{:x){a.
(head,pal,bmp) 1!:2 <y
)
NB.* pwlin: piecewise linear function
pwlin=: 3 : 0
p=. >{.x
c=. >{:x
i=. i.&0 p<y
((1-r),r=.(y-~i{p)%-/(i-0 1){p)+/ .* (i- 0 1){c
)
hue=: <.@(0.5&+)@(((6%~i.7);255*|."1#:7|3^i.7)&pwlin)"0
NB. ix=. ,0 1 2 3+/4*i.4
NB. pal2=: >,ix{|:ix{16 16$<"1 FULLSPECPAL
NB. Change bar colors in bar plots.
NB.STDCLR_jzplot_=: >,|:4 4$<"1 >,0{"(1) (i.16)|."(0 1) 16 16$<"1 pal11_38_base_
NB. Different with J5.04:
NB. RGCLR_jzplot_=: >,|:4 4$<"1 >,0{"(1) (i.16)|."(0 1) 16 16$<"1 pal11_38_base_
NB. Or, to change "plot" colors:
NB. RGCLR_jzplot_=: ADJPAL
stdColorVariants=: 0 : 0
NB. Or, something like this (for 28 colors):
hl=. <.-:#pp=. <"1 pal11_38
pp=. ,(hl{.pp),.hl}.pp
STDCLR_jzplot_=: >,|:4 7$(256$9{.1)#pp
NB. Maybe we want light and dark to alternate more:
alt=. (#STDCLR_jzplot_)$0 1
max=. 255-"(0 1)STDCLR_jzplot_
STDCLR_jzplot_=: <.STDCLR_jzplot_+max<.(128*alt)*255%~max
NB. Or (for, e.g. 42 colors):
$>,&.>/6 InterpPts (11{AllZ2Zs){CORNERS
NB. 42 3
pp=: 1 roundNums >,&.>/6 InterpPts (11{AllZ2Zs){CORNERS
STDCLR_jzplot_=: >,|:6 7$<"1 pp
pp viewmat 6 7$i.42
)
mydefault_jwplot_=: 3 : 0
BANDCOLOR=: BANDCOLOR_base_
)
holdoff=: 0 : 0
MINWH_jviewmat_=: 1000 1000 NB. Minimum viewmat size.
mat=: +/~1 o. 4*o. N%~i.--:N=: 60
mat=: +/~1 o. 4*o. N%~i.-:N=: 1400
mat1k=: +/~1 o. 4*o. N%~i.--:N=: 2000
)
NB. FULLSPECPAL viewmat roundNums 0 255 scaleNums |."1|.mat
NB. glfile_jgl2_ 'C:\amisc\apl\apl2003\logowork\matView.bmp'
NB. glsavebmp_jgl2_ 1000 1000
NB. glsavebmp_jgl2_ 1276 973 NB. Exactly right for full-screen (laptop)
NB. glfile_jgl2_ LD,'matView.bmp'
NB. 'surface;viewpoint _4 2 3;mesh 0' plot mat
NB. or
NB. pd 'viewpoint _4 _5 7' [ pd 'mesh 0' [ pd 'type surface' [ pd 'new' [ pd 'reset'
NB. pd 'show' [ pd mat
NB. pd 'savebmp C:\amisc\apl\apl2003\LogoWork\matPlot.bmp 1070 1070'
NB. Big font 680, smaller 392.
NB. Big single letter font 716 Elephant bold; text 24 DyalogAPL TT bold.
LD=: 'C:\amisc\apl\apl2003\LogoWork\' NB. Logo dir
NB. pd 'savebmp ',LD,'matPlot.bmp 1070 1070'
getLetter=: 3 : 0
NB.* getLetter: get letter in bitmap file and fit within bounds of numeric
NB. mat after compressing (e.g. cprs=. 1->no compression, 1 0->half, etc.)
'lettFl mat cprs'=. y
rc=. 0=readbmp lettFl NB. Cvt to boolean; 1=black.
rcs=. |:((1{$rc)$cprs)#|:((0{$rc)$cprs)#rc NB. Compress letter.
rcsb=. ($mat){.(<._0.5*($mat)+$rcs){.rcs NB. Center w/in mat.
rcsb=. |."1 |:rcsb NB. Orient top->away
NB.EG A=. getLetter 'A_Elephant440.bmp';mat;<10{.1 NB. letter 1/10 size.
NB.EG 'A P L'=. getLetter&.>((<LD),&.>'APL',&.><'_Elephant440.bmp');&.><mat;<1
)
blendLettWMat=: 3 : 0
NB.* blendLettWMat: blend boolean letter mat with numeric mat.
'lett mat factor'=. y
(factor*lett)+(-.lett)*roundNums 0 255 scaleNums mat
NB. 'surface;mesh 0' plot blendLettWMat lett;mat;<255
NB. FULLSPECPAL viewmat |.|:blendLettWMat lett;mat;<127
)
layLettOnMat=: 3 : 0
NB.* layLettOnMat: lay boolean letter mat on top of numeric mat.
'lett mat height'=. y
(height*lett)+roundNums (0,255-height) scaleNums mat
NB. 'surface;mesh 0' plot layLettOnMat lett;mat;<40
NB. FULLSPECPAL viewmat |.|: layLettOnMat lett;mat;<60
)
layLettOnMat2=: 3 : 0
NB.* layLettOnMat: lay boolean letter mat on top of numeric mat.
'lett mat height'=. y
roundNums 0 255 scaleNums (height*lett)+0 255 scaleNums mat
NB. 'surface;mesh 0' plot layLettOnMat2 lett;mat;<40
NB. FULLSPECPAL viewmat |.|: layLettOnMat2 lett;mat;<60
)
NB. glsavebmp_jgl2_ 1000 1000 [ glfile_jgl2_ LD,'l75L60View.bmp'
NB. require 'images'
ALP64=: '0123456789',(a.{~,((i.26)+"(1 0)a. i. 'aA')),'-+'
encimage64=: 3 : 0
NB.* encimage64: encode image file into 64 (printable) character format.
fl=. read_image y
bv=. ,(8$2)#:(,(4$256)#:$fl),,fl
ALP64{~2#.bv$~6,~6%~#bv
NB.EG plain64=. encimage64 '\amisc\pix\testColors.jpg'
)
unencimage64=: 3 : 0
NB.* unencimage64: convert 64 character format->original array.
jpg64=. y
bvun=. ,(6$2)#:ALP64 i. jpg64
raveled=. 2#.bvun$~8,~8%~#bvun
(256#.3 4$raveled)$12}.raveled
NB.EG (unencimage64 plain64) write_image '\amisc\pix\testColors64.jpg'
)
NB. From DHMUtils.ijs - avoid loading.
roundNums=: 3 : 0
NB.* roundNums: round numbers y to precision x, e.g.
NB. 0.1 roundNums 1.23 3.14159 2.718 -> 1.2 3.1 2.7.
NB. Optional 2nd left argument is single letter specifying
NB. type of rounding: Up, Down, or Banker's. Default
NB. banker's rounding (round halves up or down depending on
NB. parity of next (scaled) digit) tends to randomize bias.
1 roundNums y
:
RT=. 'B' NB. Default to Banker's rounding
TO=. x NB. Precision to which to round.
if. (2=#x)*.1=L. x do. 'TO RT'=. x end.
scaled=. y%TO
if. 'B'=RT do. RN=. 0.5*(0~:2|<.scaled)+.0.5~:1|scaled
elseif. 'D'=RT do. RN=. 0.5*.(0.5=1|scaled){1 _1 NB. Round down if last
elseif. 'U'=RT do. RN=. 0.5 NB. digit even, up if odd.
end.
TO*<.scaled+RN
)