Define palette color based on the range of z values from a data file - range

Suppose I have a data file with x y z column, which looks like:
-3.063052922487259 -3.141592741012573 401.3000000000000
-3.063052922487259 -3.063052922487259 1.290000000000000
-3.063052922487259 -2.984513103961945 0.920000000000000
-2.984513103961945 -3.141592741012573 0.100000000000000
-2.984513103961945 -3.063052922487259 10.80000000000000
-2.984513103961945 -2.984513103961945 1001.290000000000
-2.905973285436630 -2.984513103961945 514.4000000000000
-2.905973285436630 -2.905973285436630 131.0300000000000
-2.905973285436630 -2.827433466911316 129.3300000000000
The range of the values within the z column will define the color of the data points. For example, on the z column, if the value is between 0.0 and 0.3, the color of data points will be set as blue; if between 0.3 and 1, the color of data points will be set as orange; if between 400 and 1000, the color of data points will be set as navy.
So I write some code like this:
set xrange [0:15]
set yrange [0:-15]
set zrange [0:1400]
set cbrange [0.001:1400]
set palette defined ( 0 "goldenrod", 0.3 "blue", 1 "orange", 2 "cyan", 4 "yellow", 10 "green", 20 "pink", 50 'gold', 100 'purple', 400 'navy', 1000 "red")
set palette maxcolors 11
unset key
unset surface
splot "DATA.dat" using 1:2:3 with image
Which does not work. Any help?
Further update:
I really want to explain clearer why does not work, but Stack Overflow does not allow me to further explain, because they require me to have 10 reputation points in order to post an image result. So I can not post my result due to lacking of reputation. But I do modify my data set, so you can see the xy-data is equidistance now.
So I just describe the problem by words, instead of image, which is that the color box is wrong. According to my code, between 400 and 1000 should be navy (just one color). But the color box on the image shows that between 400 and 1000, there are 5 different navy colors, from shallow navy to deep navy. How can I only have one navy color between 400 and 1000 please?

The maxcolors option doesn't work properly in your case because it only discretizes the underlying color gradient. You can use the test palette command to see how your actual palette looks like:
set palette defined ( 0 "goldenrod", 0.3 "blue", 1 "orange", 2 "cyan", 4 "yellow", 10 "green", 20 "pink", 50 'gold', 100 'purple', 400 'navy', 1000 "red")
set palette maxcolors 11
test palette
You must also keep in mind, that the numbers used in the palette definition aren't absolute values on the cb-axis, but the values (in your case from 0 to 1000) are mapped to the actual cbrange (0.001 to 1400).
In order to get regions with constant color value, you do the following:
set palette defined (0 "goldenrod", \
0 "blue", 0.3 "blue", \
0.3 "orange", 1 "orange", \
1 "cyan", 2 "cyan", \
2 "yellow", 4 "yellow", \
4 "green", 10 "green", \
10 "pink", 20 "pink", \
20 "gold", 50 "gold", \
50 "purple", 400 "purple", \
400 "navy", 1000 "navy", \
1000 "red", 1400 "red")
test palette

Related

How to find all the rows that share the same value on two columns?

Dataset example:
sex favourite_meal favourite_color age weight(kg)
Tom M pizza red 18 90
Jess F lasagna blue 20 43
Mark M pizza red 30 68
David M hamburger purple 25 70
Lucy F sushi green 18 47
How can I compare each row with the others and find which one share for example the same (sex,favourite_meal) couple. The idea is to check on a large dataset which rows share the same values on two attributes (columns). In this example would be Tom and Mark which share (M, pizza); how to do the same on a large dataset where you can't check by eye?
One awk option is process the source data twice. First get the count of uniq values in columns 2 and 3 into an array. Then use those counts to filter the data:
awk 'NR==FNR {p[$2" "$3]++} FNR<NR {for(n in p) if (p[n]>1 && $2" "$3==n) { print}}' m.dat m.dat
Tom M pizza red 18 90
Mark M pizza red 30 68
you can use pandas to do this
import pandas as pd
# Initialize data to Dicts of series.
d = {'Name': pd.Series(['Tom', 'Jess', 'Mark', 'David', 'Lucy']),
'sex': pd.Series(['M', 'F', 'M', 'M', 'F']),
'favorite_meal': pd.Series(['pizza', 'lasanga', 'pizza', 'hamburger', 'sushi']),
'favorite_color': pd.Series(['red', 'blue', 'red', 'purple', 'green']),
'age': pd.Series([18, 20, 30, 20, 18]),
' weights(kg)': pd.Series([90, 43, 68, 70, 47])
}
df = pd.DataFrame(d)
for y, x in df.groupby(['favorite_meal', 'sex']):
print("....................")
print(x.to_string(index=0, header=0))
In each iteration, the for loop is operating on a set of similar rows.

Check values against a set of allowed values

I want to check values in one table against a mapping table.
Data Table:
ID
Color
Object
001
Green
Grass
002
Green
Tree
003
Green
Sky
004
Green
Apple
005
Red
Apple
006
Red
Poppy
007
Red
Water
Allowed Mappings
MappingID
MappingKey
MappingValue
M001
Green
Grass
M002
Green
Tree
M003
Green
Apple
M004
Red
Apple
M005
Red
Poppy
The expected output is the entries that are not foreseen in the mapping table.
Output:
ID
Color
Object
003
Green
Sky
007
Red
Water
Here are the dataframe definitions so you can get started more easily:
data_df = spark.createDataFrame(
[
("001", "Green", "Grass"),
("002", "Green", "Tree"),
("003", "Green", "Sky"),
("004", "Green", "Apple"),
("005", "Red", "Apple"),
("006", "Red", "Poppy"),
("007", "Red", "Water")
],
["ID", "Color", "Object"],
)
mapping_df = spark.createDataFrame(
[
("M001", "Green", "Grass"),
("M002", "Green", "Tree"),
("M003", "Green", "Apple"),
("M004", "Red", "Apple"),
("M005", "Red", "Poppy")
],
["MappingID", "MappingKey", "MappingValue"],
)
You can use left_anti join.
join_on=[
data_df.Color == mapping_df.MappingKey,
data_df.Object == mapping_df.MappingValue
]
df = data_df.join(mapping_df, on=join_on, how='left_anti')

Netlogo foreach nested list

I am trying to port an older code to the latest (6.0.1), the following foreach loop works fine on Netlogo 4.1.3 but when copy and paste the code into version 6.0.1 the "item 0 ?" does not work. It says the "?" is undefined. That line of code is suppose to retrieve the item of the list inside the segment
to setup-row [row colour segments]
foreach segments
[
if pycor = row * row-patches-width and
(pxcor >= col-patches-width * (item 0 ?)) and (pxcor <= col-patches-
width * (item 1 ?))
[set pcolor colour
output-print item 0 ?]
]
end
The passed in "segments" variable contains the following lists:
setup-row 4 blue [[-8 -5] [-3 -1] [0 3] [5 9]]
If the code is working correctly, it should retrieve the -8 with (item 0 ?) and -5 with (item 1 ?) and so on. What I assumed in the old code is that the "?" are the first list retrieved from segments which is [-8 -5] and (item 0 ?) retrieved the -8 and (item 1 ?) retrieved the -5.
I have tried to read through the new user manual to find something that works similarly but to no avail or maybe I didn't look in the right place. Hope some of you can point me in the right direction.
Yep, that's been changed in Netlogo 6.0- see the transition guide page. For more detail on the new foreach syntax, see the dictionary entry. Basically, instead of using ? now, you explicitly define the variable names to use in the foreach procedure. Following your list example above:
to foreach-example
let ex [ [-8 -5] [-3 -1] [0 3] [5 9] ]
foreach ex [
[ xy_coords ] ->
ask patches with [ pxcor = (item 0 xy_coords) and pycor = ( item 1 xy_coords) ] [
set pcolor white
]
]
end
Here, I explicitly state that the list items will be called "xy_coords" throughout the procedure. It's a nice change that allows for more readable code since your variables can have more meaningful names.

polyhedron in openSCAD yields "No top level geometry to render"

I do not get why this polyhedron gives me a "no top level geometry to render" error. All triangles are correctly oriented, "thrown-together"-view shows only yellow outside faces. This is my code:
top_width=39;
bottom_width=51;
col_offset=6;
length=160;
height=40;
rows=10;
cols=40;
top_row_width=top_width/rows;
bottom_row_width=bottom_width/rows;
col_length=length/cols;
walls=0.4;
box();
module box(){
polyhedron(
points=[
[ // point 0
0,
0,
height
],[ // point 1
length,
0,
height
],[ // point
length,
top_width,
height
],[ // point 3
0,
top_width,
height
],[ // point 4
0,
0+col_offset,
0
],[ // point 5
length,
0+col_offset,
0
],[ // point 6
length,
bottom_width+col_offset,
0
],[ // 7
0,
bottom_width+col_offset,
0
]
],
triangles=[
[3,1,0],
[3,2,1],
[4,5,6],
[4,6,7],
[7,2,3],
[6,2,7],
[4,3,0],
[4,7,3],
[1,2,5],
[1,2,5],
[2,6,5],
[0,1,5],
[0,5,4]
]
);
}
Any hint is very appreciated, thanks in advance!
Well I'm baffled too. Latest version of OpenSCAD supports faces in place of triangles:
faces = [
[0,3,2,1],
[0,1,5,4],
[1,2,6,5],
[2,3,7,6],
[0,4,7,3],
[4,5,6,7] ]
and that renders OK.
You might try asking on the OpenSCAD forum http://forum.openscad.org/ which is more active than here.

How to create interactive chart with Rebol

I have this code to create a candlestick chart in rebol. Now I'd like to use over feel http://www.rebol.com/how-to/feel.html#section-6 to show info on each candlestick but my box is drawn with draw dialect and it doesn't seem to accept event ?
plot: [
pen green line 5x404 5x440 pen gold fill-pen 0.255.0 box 3x424 7x418 line 10x396 10x422 pen gold fill-pen 0.255.0 box 8x418 12x402 line 15x397 15x436 pen gold fill-pen 255.0.0 box 13x401 17x435 line 20x429 20x447 pen gold fill-pen 255.0.0 box 18x434 22x446 line 25x441 25x464 pen gold fill-pen 255.0.0 box 23x446 27x463 line 30x445 30x493 pen gold fill-pen 255.0.0 box 28x461 32x482 line 35x470 35x504 pen gold fill-pen 255.0.0 box 33x481 37x492 line 40x466 40x498 pen gold fill-pen 0.255.0 box 38x491 42x477
]
grid: [1100 600]
step-grid: 5
max-n-points: (grid/1 / step-grid) - 1
x-axis-border: 20
Y-margin: 10
X0: 5
grid-color: coal
main: layout [
origin 20x0
space 1x1
panel1: box 1100x580 black effect reduce [
'line-pattern 4 4
'grid 30x30 0x0 (grid-color)
'draw plot
]
panel2: box 1100x0 black
panel3: box 1100x20 black
]
view main
Here is a little expansion of my previous answer related to your chart viewer.
there are many ways you may adapt it, but it should give you some ideas into solving your problem.
rebol []
plot: []
data: reduce [ ]
refresh: func [/local clr delta prev-pos pos] [
clear plot
prev-pos: 0x300
foreach [clr delta] data [
pos: prev-pos + (delta * 0x1) + 7x0
append plot compose [
pen (clr) line (prev-pos) (pos) fill-pen (clr) pen none circle dot-size (pos)
]
prev-pos: pos
]
show panel1
]
add-data: func [i][loop i [append data reduce [(random white * .85) + (white * .15) (-20 + random 40)]] refresh]
grid: [800 600]
step-grid: 5
max-n-points: (grid/1 / step-grid) - 1
x-axis-border: 20
Y-margin: 10
X0: 5
grid-color: coal
dot-size: 3
viewer-size: 800x580
; open up console before vid window
main: layout [
origin 20x0
space 1x1
field 800
panel1: box viewer-size black rate 30 effect [
line-pattern 4 4
grid 30x30 0x0 grid-color
draw plot
] feel [
;probe first panel1
over: func [face over? offset /local d][
panel1/pane: either over? [info-pane][none]
if over? [
d: offset/x - face/offset/x - 1
d: (to-integer d / 7) * 2 + 1
either d: pick data d [
info-box/text: to-string d
][
panel1/pane: none
]
]
]
engage: func [face action event] [
switch action [
down [
drag-start: event/offset
]
up [
drag-end: event/offset
scroll-size: to-integer abs ((pick (drag-start - drag-end) 1) / 5)
]
time [
info-box/offset: event/offset - 20x20 ; the offset is the main-window origin
show main
]
]
]
]
panel2: box 800x0 black
panel3: box 800x20 black
]
insert-event-func [
either all [
event/type = 'key
none? system/view/focal-face
][
print ["shortcut: " event/key]
switch event/key [
; escape
#"^[" [quit]
; enter/return
#"^M" [print "resampling data" clear data add-data 100]
up [dot-size: dot-size + 1 show panel1]
down [dot-size: dot-size - 1 show panel1]
left [clear skip tail plot -12 clear skip tail data -2 show panel1]
right [add-data 2]
]
none
][
event
]
]
info-box: make face [
offset: 0x0
color: white * .2
size: 150x30
text: "0.0.0"
font: make font [valign: 'middle style: [bold italic]]
]
info-pane: reduce [info-box]
add-data 100
refresh
view/options main [all-over]
focus panel1
Note that as we move the mouse over the chart, we are only using the X component of the mouse to figure out what to display. Better systems are obvious, but this is sufficient to illustrate what needs to be done to receive all mouse move events and act on them.
Also note that the over feel receives Window offsets, so you must remove the face's offset to get the real face-relative coordinates.
PS: The red arrow above, is my mouse cursor.