Next: three, Previous: graph, Up: Base modules
palette
Asymptote
can also generate color density images
and palettes. The following palettes are predefined in
palette.asy
:
pen[] Grayscale(int NColors=256)
pen[] Rainbow(int NColors=65501)
pen[] BWRainbow(int NColors=65485)
pen[] BWRainbow2(int NColors=65485)
The function cmyk(pen[] Palette)
may be used to convert any
of these palettes to the CMYK colorspace.
A color density plot using palette palette
can be generated from
a function f
(x,y) and added to a picture pic
:
bounds image(picture pic=currentpicture, real f(real,real), range range=Full, pair initial, pair final, int nx=ngraph, int ny=nx, pen[] palette);The function
f
will be sampled at nx
and ny
evenly spaced points over a rectangle defined by the points
initial
and final
, respecting the current graphical
scaling of pic
. The color space is scaled according to the
z axis scaling (see automatic scaling). A bounds structure
for the function values is returned:
struct bounds { public real min; public real max; // Possible tick intervals: public int[] divisor; }This information can be used for generating an optional palette bar. The palette color space corresponds to a range of values specified by the argument
range
, which can be Full
, Automatic
,
or an explicit range Range(real min, real max)
.
Here Full
specifies a range varying from the
minimum to maximum values of the function over the sampling interval,
while Automatic
selects "nice" limits.
The example imagecontour.asy
illustrates how level sets
(contour lines) can be drawn on a color density plot (see contour).
A color density plot can also be generated from an explicit real[][]
array data
:
bounds image(picture pic=currentpicture, real[][] f, range range=Full, pair initial, pair final, pen[] palette, bool transpose=(initial.x < final.x && initial.y < final.y));If the initial point is to the left and below the final point, by default the array indices are interpreted according to the Cartesian convention (first index: x, second index: y) rather than the usual matrix convention (first index: -y, second index: x).
To construct an image from an array of irregularly spaced points
and an array of values f
at these points, use one of the routines
bounds image(picture pic=currentpicture, pair[] z, real[] f, range range=Full, pen[] palette) bounds image(picture pic=currentpicture, real[] x, real[] y, real[] f, range range=Full, pen[] palette)
An optionally labelled palette bar may be generated with the routine
void palette(picture pic=currentpicture, Label L="", bounds range, pair initial, pair final, axis axis=Right, pen[] palette, pen p=currentpen, paletteticks ticks=PaletteTicks);The color space of
palette
is taken to be over bounds range
with
scaling given by the z scaling of pic
.
The palette orientation is specified by axis
, which may be one of
Right
, Left
, Top
, or Bottom
.
The bar is drawn over the rectangle from initial
to final
.
The argument paletteticks
is a special tick type (see ticks)
that takes the following arguments:
paletteticks PaletteTicks(Label format="", ticklabel ticklabel=null, bool beginlabel=true, bool endlabel=true, int N=0, int n=0, real Step=0, real step=0, pen pTick=nullpen, pen ptick=nullpen);
The image and palette bar can be fit to a frame and added and optionally aligned to a picture at the desired location:
size(12cm,12cm); import graph; import palette; int n=256; real ninv=2pi/n; real[][] v=new real[n][n]; for(int i=0; i < n; ++i) for(int j=0; j < n; ++j) v[i][j]=sin(i*ninv)*cos(j*ninv); pen[] Palette=BWRainbow(); picture bar; bounds range=image(v,(0,0),(1,1),Palette); palette(bar,"$A$",range,(0,0),(0.5cm,8cm),Right,Palette, PaletteTicks("$%+#.1f$")); add(bar.fit(),point(E),30E);
Here is an example that uses logarithmic scaling of the function values:
import graph; import palette; size(10cm,10cm,IgnoreAspect); real f(real x, real y) { return 0.9*pow10(2*sin(x/5+2*y^0.25)) + 0.1*(1+cos(10*log(y))); } scale(Linear,Log,Log); pen[] Palette=BWRainbow(); bounds range=image(f,Automatic,(0,1),(100,100),nx=200,Palette); xaxis("$x$",BottomTop,LeftTicks,Above); yaxis("$y$",LeftRight,RightTicks,Above); palette("$f(x,y)$",range,(0,200),(100,250),Top,Palette, PaletteTicks(ptick=linewidth(0.5*linewidth())));
One can also draw an image directly from a two-dimensional pen array:
void image(picture pic=currentpicture, pen[][] data, pair initial, pair final, bool transpose=(initial.x < final.x && initial.y < final.y));as illustrated in the following example:
size(200); import palette; int n=256; real ninv=2pi/n; pen[][] v=new pen[n][n]; for(int i=0; i < n; ++i) for(int j=0; j < n; ++j) v[i][j]=rgb(0.5*(1+sin(i*ninv)),0.5*(1+cos(j*ninv)),0); picture bar; image(v,(0,0),(1,1));