From: Ethan Merritt <merritt@u.washington.edu>  20100923 19:52:20

On Thursday 23 September 2010 11:12:11 am Ethan Merritt wrote: > On Thursday 23 September 2010 10:52:33 am Manfred Schwarb wrote: > > Am 22.09.2010 17:32, schrieb sfeam (Ethan Merritt): > > > > >> > > >> The color transition from one color to the next in discrete palettes > > >> should be at the exact pixel location. > > > > > > I do not recall seeing the original problem report. > > > Can you give us a pointer to it? > > > > > > http://sourceforge.net/mailarchive/forum.php?thread_name=201009220832.37418.sfeam%40users.sourceforge.net&forum_name=gnuplotbeta > > > OK, thanks. > > I think the underlying problem is that the code that draws the color box > was written to handle continuous color palettes. The comment "I think > no one can distinguish more than 128 colors" refers to the minimal step > within a continuous spectrum. > > I don't have any code to offer, but I think the best solution to the > problem is to write a different routine for drawing discrete palettes. After playing around with nonlinear discrete palettes like the one in your problem figures, I have become suspicious that the problem is more serious than just the resolution of the color box. The palette colors assigned to individual points are also wrong. That is, the bad coloring in the color box is a correct representation of the coloring assigned to elements of the plot. Now it may be that the way I constructed a test palette is not a good way to do it. I'll show my test below. set palette defined (0 "purple", 1 "blue", \ 1 "blue", 2 "darkgreen", \ 2 "darkgreen", 4 "springgreen", \ 4 "springgreen", 8 "yellow", \ 8 "yellow", 16 "orange", \ 16 "orange", 32 "red" \ ) set xrange [0:32] set cbrange [0:32] set ytics 2 set cbtics 2 set grid y plot '+' using 1:1:1 with points lt 7 lc palette pause 1 # Limiting the number of colors makes it much worse, and clarifies that the # error comes from assigning colors to the palette in equal increments # rather that looking at the requested range boundaries: set palette maxcolors 7 replot So apparently one cannot create a discrete palette this way. Or at least you cannot create a discrete palette with unequal color ranges. Using "show palette palette 7" confirms this, I think. But maybe there's another way that works better. Perhaps you could create a palette by hand and load it using set palette file 'mypalette.dat' Unfortunately the documentation is not very helpful as to exactly how color ranges are assigned to colors that are read in from a file. What commands produced the palette in your problem case? Ethan > As Dan suggested, if there are only 5 colors in the palette then we need > only draw 5 rectangles in the color box. Unlike the current code, > however, they shouldn't be evenly spaced. The endpoints of each rectangle > should be taken from the palette definition so that they will indeed be > placed with perfact accuracy. > > Ethan > > > > > It is perhaps in your SPAM folder. Sorry for this, I used a wrong > > outgoing mail server to send the email. > > > > Probably my hack is wrong indeed, but it works for my use case. > > > > Thanks for looking at it, cheers, > > > > Manfred > > > > > > > > > > > >> There is some obvious cleanup possibility in this function, as > > >> > > >> (xy_to  xy_from) == (color_box.rotation == 'h' ? color_box.bounds.xright  color_box.bounds.xleft : color_box.bounds.ytop  color_box.bounds.ybot) > > >> > > >> so one can drop the redundant ifcondition. > > >> > > >> > > >> And when xy_step === 1, one can eliminate this variable completely, > > >> which would make the loop less heavyweight. > > > > > > One step in coordinate space is not the same as one pixel. > > > Many terminals track coordinates at higher resolution. > > > x11 axis coordinates run from [0:4096], but the pixel resolution is > > > typically smaller by a factor of 510. The cairo terminals, > > > including wxt, oversample by a factor of 20. The canvas terminal > > > by a factor of 10. And so on. > > > > > > There is currently no way that I know of for the gnuplot core > > > code to know the pixel resolution of the output device. > > > > > > Ethan > > > > > >> > > >> > > >> Which would lead to some thing like: > > >>  color.c.orig 20100921 14:09:41.000000000 +0200 > > >> +++ color.c 20100922 09:16:05.000000000 +0200 > > >> @@ 361,9 +361,8 @@ > > >> static void > > >> draw_inside_color_smooth_box_bitmap(FILE * out) > > >> { > > >>  int steps = 128; /* I think that nobody can distinguish more colours drawn in the palette */ > > >>  int i, xy, xy2, xy_from, xy_to; > > >>  double xy_step, gray; > > >> + int i, xy, xy2, xy_from, xy_to, steps; > > >> + double gray; > > >> gpiPoint corners[4]; > > >> > > >> (void) out; /* to avoid "unused parameter" warning */ > > >> @@ 378,7 +377,7 @@ > > >> xy_from = color_box.bounds.xleft; > > >> xy_to = color_box.bounds.xright; > > >> } > > >>  xy_step = (color_box.rotation == 'h' ? color_box.bounds.xright  color_box.bounds.xleft : color_box.bounds.ytop  color_box.bounds.ybot) / (double) steps; > > >> + steps = xy_to  xy_from; > > >> > > >> for (i = 0; i < steps; i++) { > > >> gray = (double) i / steps; /* colours equidistantly from [0,1] */ > > >> @@ 386,14 +385,14 @@ > > >> gray = 1  gray; > > >> /* Set the colour (also for terminals which support extended specs). */ > > >> set_color(gray); > > >>  xy = xy_from + (int) (xy_step * i); > > >>  xy2 = xy_from + (int) (xy_step * (i + 1)); > > >> + xy = xy_from + i; > > >> + xy2 = xy + 1; > > >> if (color_box.rotation == 'v') { > > >> corners[0].y = corners[1].y = xy; > > >>  corners[2].y = corners[3].y = (i == steps  1) ? xy_to : xy2; > > >> + corners[2].y = corners[3].y = xy2; > > >> } else { > > >> corners[0].x = corners[3].x = xy; > > >>  corners[1].x = corners[2].x = (i == steps  1) ? xy_to : xy2; > > >> + corners[1].x = corners[2].x = xy2; > > >> } > > >> #ifdef EXTENDED_COLOR_SPECS > > >> if (supply_extended_color_specs) { > > >> > > >> > > >> Cheers, Manfred > > >> > > >> > > >> > > >>> See what the rest of the list thinks. > > >>> > > >>> Dan > > >>> > > >>> > > >>> Manfred Schwarb wrote: > > >>>> Am 21.09.2010 17:24, schrieb Daniel J Sebald: > > >>>> > > >>>> > > >>>>> Something certainly doesn't look right with the original. However, > > >>> putting the resolution so high doesn't seem like the best solution. At the > > >>> same time, limiting to 128 steps seems restrictive. I would think it all > > >>> depends on how the user sets up the color axis. For example, if only five > > >>> colors are used, perhaps only five levels are needed, so long as the color > > >>> ticks align with the color box representation. > > >>>>> > > >>>> > > >>>> > > >>>> > > >>>> Hmm, no I think it does not depend on the number of used colors. > > >>>> As soon as one wants a discrete palette, placing has to be accurate to > > >>>> pixel resolution. > > >>>> Which means, if one does not want to calculate each color transition > > >>>> separately somehow, one has to draw in pixel resolution, i.e. > > >>>> each pixel line separately. > > >>>> > > >>>> The following gives good results for me: > > >>>> > > >>>>  color.c.orig 20100921 14:09:41.000000000 +0200 > > >>>> +++ color.c 20100921 22:42:01.000000000 +0200 > > >>>> @@ 361,7 +361,7 @@ > > >>>> static void > > >>>> draw_inside_color_smooth_box_bitmap(FILE * out) > > >>>> { > > >>>>  int steps = 128; /* I think that nobody can distinguish more > > >>> colours drawn in the palette */ > > >>>> + int steps; > > >>>> int i, xy, xy2, xy_from, xy_to; > > >>>> double xy_step, gray; > > >>>> gpiPoint corners[4]; > > >>>> @@ 378,6 +378,8 @@ > > >>>> xy_from = color_box.bounds.xleft; > > >>>> xy_to = color_box.bounds.xright; > > >>>> } > > >>>> + steps=xy_toxy_from; > > >>>> + > > >>>> xy_step = (color_box.rotation == 'h' ? color_box.bounds.xright  > > >>> color_box.bounds.xleft : color_box.bounds.ytop  color_box.bounds.ybot) / > > >>> (double) steps; > > >>>> > > >>>> for (i = 0; i < steps; i++) { > > >>>> > > >>>> > > >>>> In my example, steps becomes 499, which is much smaller > > >>>> than my insane 12800. > > >>>> What do you think? > > >>>> > > >>>> Cheers, > > >>>> Manfred > > >>>> > > >>>> > > >>>> > > >>>> > > >>>>> Dan > > >>>>> > > >>>>> > > >>>>> Manfred Schwarb wrote: > > >>>>> > > >>>>>> Hi, > > >>>>>> > > >>>>>> when doing 2d plots ("splot") with discrete colors > > >>>>>> [i.e. 'set palette defined ( 0 "yellow", 0.5 "yellow", 0.5 "red", 1 > > >>> "red" )'], > > >>>>>> I get some distorted color distribution in the color box. > > >>>>>> > > >>>>>> I then discovered that the reason is the coarse stepping > > >>>>>> in calculating the color values. > > >>>>>> The following cures it for me: > > >>>>>> > > >>>>>>  color.c.orig 20100921 14:09:41.000000000 +0200 > > >>>>>> +++ color.c 20100921 14:09:48.000000000 +0200 > > >>>>>> @@ 361,7 +361,7 @@ > > >>>>>> static void > > >>>>>> draw_inside_color_smooth_box_bitmap(FILE * out) > > >>>>>> { > > >>>>>>  int steps = 128; /* I think that nobody can distinguish more > > >>> colours drawn in the palette */ > > >>>>>> + int steps = 12800; /* I think that nobody can distinguish more > > >>> colours drawn in the palette */ > > >>>>>> int i, xy, xy2, xy_from, xy_to; > > >>>>>> double xy_step, gray; > > >>>>>> gpiPoint corners[4]; > > >>>>>> > > >>>>>> > > >>>>>> I figured that "steps" has to be in the range of 10000 to get > > >>>>>> completely accurate color value calculation. > > >>>>>> > > >>>>>> Good and bad examples as attachments. > > >>>>>> > > >>>>>> > > >>>>>> Cheers, > > >>>>>> Manfred > > >>>>>> > > >  Ethan A Merritt Biomolecular Structure Center, K428 Health Sciences Bldg University of Washington, Seattle 981957742 