I have a O/D matrix that might be useful to move people from one place to another. With the matrix extension, I attempt to build a simple model before I progress to the actual model, but ended up coding verbosely.
extensions [matrix]
globals [mat]
patches-own [location]
turtles-own [residency]
to setup
ca
reset-ticks
ask patches [
if pxcor >= 0 and pycor >= 0 [set pcolor black + 0 set location "ne" ]
if pxcor < 0 and pycor >= 0 [set pcolor black + 1 set location "nw" ]
if pxcor < 0 and pycor < 0 [set pcolor black + 2 set location "sw" ]
if pxcor >= 0 and pycor < 0 [set pcolor black + 3 set location "se" ]
]
ask n-of 40 patches [
sprout 1 [
set shape "person student"
set heading random 360
set residency [location] of patch-here
if residency = "nw" [set color yellow + 2]
]
]
set-matrix
end
to set-matrix
set mat matrix:from-row-list [[0.5 0.3 0.1 0.1][0.3 0.5 0.1 0.1][0.1 0.1 0.5 0.2][0.1 0.1 0.2 0.5]]
print matrix:pretty-print-text mat
;pretty text print looks something like this
; nw ne sw se
;nw 0.5 0.3 0.1 0.1
;ne 0.3 0.5 0.1 0.1
;sw 0.1 0.1 0.5 0.2
;se 0.1 0.1 0.2 0.5
end
to go
ifelse(ticks mod 240 <= 120)[move-out][come-home]
tick
end
to move-out
;; North West Residents
let n-of-nw count turtles with [residency = "nw"]
let %nw-nw matrix:get mat 0 0
let %nw-ne matrix:get mat 0 1
let %nw-sw matrix:get mat 0 2
let %nw-se matrix:get mat 0 3
ask n-of (%nw-nw * n-of-nw) turtles with [residency = "nw"]
[rt 45 lt 45 set heading random 360 fd 2
face min-one-of patches with [location = "nw"][distance myself]]
ask n-of (%nw-ne * n-of-nw) turtles with [residency = "nw"]
[ifelse location = "ne"[face min-one-of patches with [location != "nw" and location = "ne"][distance myself]
rt 45 lt 45 set heading random 360 fd 2]
[rt 45 lt 45 set heading random 360 fd 2]]
ask n-of (%nw-sw * n-of-nw) turtles with [residency = "nw"]
[ifelse location = "sw"[face min-one-of patches with [location != "nw" and location = "sw"][distance myself]
rt 45 lt 45 set heading random 360 fd 2]
[rt 45 lt 45 set heading random 360 fd 2]]
ask n-of (%nw-se * n-of-nw) turtles with [residency = "nw"]
[ifelse location = "se"[face min-one-of patches with [location != "nw" and location = "se"][distance myself]
rt 45 lt 45 set heading random 360 fd 2]
[rt 45 lt 45 set heading random 360 fd 2]]
ask turtles with [residency != "nw"][rt 45 lt 45 set heading random 360 fd 1]
end
to come-home
ask turtles with [residency = "nw"]
[ifelse location != "nw" [face min-one-of patches with [location = "nw"][distance myself] fd 1]
[move-to one-of neighbors with [location = "nw"]]]
ask turtles with [residency != "nw"][rt 45 lt 45 set heading random 360 fd 1]
end
Inside the Netlogo world, four regions splitted up at each corner as northwest(nw), northeast(ne), southwest(sw), southeast(se). I created agents in a random space and assigned their residency according to their location. Then, I wrote a origin-destination matrix as below,
nw ne sw se
nw 0.5 0.3 0.1 0.1
ne 0.3 0.5 0.1 0.1
sw 0.1 0.1 0.5 0.2
se 0.1 0.1 0.2 0.5
where, for example, 30% of nw residents should move to ne. I only coded one region, but can anyone give comments to improve my code more sound? Many thanks in advance.
Okay, if you have separated identifying where to go from moving toward the destination, this is a cleaner version. It is not tested. I have scrapped the matrix since that was making you triple-handle choosing where to go. NetLogo doesn't have a 'choose case' type structure so nested ifelse is the way to go.
I also added some randomness to the direction since I think that was what you were trying to do with all the heading code.
patches-own [location] turtles-own [residency destination]
to setup
clear-all
ask patches [
if pxcor >= 0 and pycor >= 0 [set pcolor black + 0 set location "ne" ]
if pxcor < 0 and pycor >= 0 [set pcolor black + 1 set location "nw" ]
if pxcor < 0 and pycor < 0 [set pcolor black + 2 set location "sw" ]
if pxcor >= 0 and pycor < 0 [set pcolor black + 3 set location "se" ]
]
ask n-of 40 patches
[ sprout 1
[ set shape "person student"
set heading random 360
set residency [location] of patch-here
if residency = "nw" [set color yellow + 2]
choose-destination
]
]
reset-ticks
end
to go
ifelse(ticks mod 240 <= 120)[move-out][come-home]
tick
end
to choose-destination
ask turtles with [residency = "nw"]
[ let myrandom random-float 1
ifelse myrandom <= 0.5 [ set destination "nw" ] [
ifelse myrandom <= 0.8 [ set destination "ne" ] [
ifelse myrandom <= 0.9 [ set destination "sw" ] [
set destination "se" ]]]
; similar code for each residency
end
to move-out
ask turtles with [destination != location]
[ face min-one-of patches with [location = destination][distance myself]
set heading heading + 10 - random 20
forward 1 ]
end
to come-home
; code more like revised move-out
end
Okay algebra and trig are not my strong suit by any means so here is what I need to do.
I have a circle which is measured in degrees from +180 to -180 (360 total)
Given the center point of the circle stays the same, Cx , Cy.
The angle varies from -180 to +180
I need to locate a point that regardless the given angle is + 3 units away that is at the 90 degree position and the 270 degree position (from the given degrees)
So like...
Angle = 0
Point 1 -> x = 0, y -3
Point 2 -> x = 0, y + 3
And if the angle was say 90 (provided its measured Clockwise)
Point 1 -> x = -3, y = 0
Point 2 -> x = 3, y = 0
What I need is a forumla that will accept Angle, then tell me what my x/y should be 3 units away from the origin.
I have tried: EDIT Updated to double precision using Java.
`double x = Cx + 3 * Math.cos((d + 90) * Math.PI / 180);'
'double y = Cy + 3 * Math.sin((d + 90) * Math.PI / 180);`
this gives me mixed results, I mean sometimes it's where I think it should be and other times its quite wrong.
Assuming Cx = 0.500, Cy = 0.500
Sample Data: Result:
Deg = 0 x = 2 / y = 5
Deg = 90 x = -1 / y = 2
Deg = 125 x = -0.457 / y = 0.297
Deg = 159 x = 0.924 / y = -0.800
I realize I am only calculating one point at this point but do you have any suggestions on how to get the first point working? at say 90 degrees from whatever degree I start with?
x = Cx + r * Math.cos( (d+90) * Math.PI / 180 );
y = Cy + r * Math.sin( (d+90) * Math.PI / 180 );
Seems that this is the correct formula for what I was trying to accomplish. This will take any value for Cx/Cy's origin add the Radius r, then calculate the degrees + 90 and convert to radians.. Once all that magic takes place, you're left with an x/y coord that is 90 degrees of where you started.
Base on gnuplot example about "Heat map with non-zero pixel values written as labels" in here:
http://gnuplot.sourceforge.net/demo_cvs/heatmaps.html
I have data:
6 5 4 3 1 0
3 2 2 0 0 1
0 0 0 0 1 0
0 0 0 0 2 3
0 0 1 2 4 4
0 1 2 3 4 6
and my gnuplot:
set terminal pngcairo enhanced font "arial,10" fontscale 1.0 size 500, 350
set output 'heatmaps.png'
unset key
set view map
set xtics border in scale 0,0 mirror norotate offset character 0, 0, 0 autojustify
set ytics border in scale 0,0 mirror norotate offset character 0, 0, 0 autojustify
set ztics border in scale 0,0 nomirror norotate offset character 0, 0, 0 autojustify
set nocbtics
set rtics axis in scale 0,0 nomirror norotate offset character 0, 0, 0 autojustify
set xrange [ -0.500000 : 4.50000 ] noreverse nowriteback
set yrange [ -0.500000 : 4.50000 ] noreverse nowriteback
set cbrange [ 0.00000 : 5.00000 ] noreverse nowriteback
set palette rgbformulae -7, 2, -7
splot 'heatmap.txt' matrix using 1:2:3 with image, \
'heatmap.txt' matrix using 1:2:($3 == 0 ? " " : sprintf("$3") ) with labels
this script just printout "3" in every labels. Could you help me? thanks
and also label for Xtics and Ytics
Tipe1 Tipe2 Tipe3 Tipe4 Tipe5
Failure1 6 2 0 0 1
Failure2 0 0 0 1 0
Failure3 0 0 0 2 3
Failure4 0 1 2 4 4
Failure5 1 2 3 4 6
Thanks again
I think the problem is the wrong call to the sprintf function.
sprintf(format,values)
You should call sprintf with a decimal number in format (%d) and the label value you want to display (third column $3) :
sprintf("%d",$3)
I copied your data into a file (named data) and this example works well :
plot 'data' matrix using 1:2:3 with image, '' matrix using 1:2:($3==0 ? " " : sprintf("%d",$3)) with labels
Hope it helps!
Here's my code for a little pattern that looks something like this. (Not the most efficient code I know). Now, I want to make stars rotate using animate. but I'm not sure how to use display and animate together in one program. Any help would be appreciated. Thanks.
import Graphics.Gloss
main = display (InWindow "Gloss" (700,700) (0,0))
black (picture 100)
picture :: Float -> Picture
picture 0 = text "Value cannot be 0"
picture number = scale 6.5 6.5 (color rose $ drawpicture number)
orangered, orangered2, orangered3 :: Color
orangered = makeColor 1.0 0.251 0.0 0.7
orangered2 = makeColor 1.0 0.251 0.0 0.5
orangered3 = makeColor 1.0 0.251 0.0 0.3
intervalsmall = [0,11.25,22.5,33.75,45,56.25,67.5,78.75]
intervalbig = [0,22.5,45,67.5,90,112.5,135,157.5,180,202.5,225,247.5,270,292.5,315,337.5]
xlist = [2,4..50]
ylist = [0,2..48]
squares = pictures[rotate x (line [(-50,0),(0,50),(50,0),(0,-50),(-50,0)]) | x <- intervalsmall]
stars = pictures[rotate x ((pictures [line [(-8.5,0),(0,50),(8.5,0)],line[(0,50),(0,0)]])) | x <- intervalbig]
grid = pictures[line [(0,y),(x,50)] | x <- xlist, y <- ylist, x-y==2]
insidegrid = pictures[
translate 0 (-50) grid,
rotate 90 (translate 0 (-50) grid),
rotate 180 (translate 0 (-50) grid),
rotate 270 (translate 0 (-50) grid)]
drawpicture :: Float -> Picture
drawpicture number = pictures [
color red (pictures [circle 50,circle 8.5]),
line [(-50,-50),(-50,50),(50,50),(50,-50),(-50,-50)],
squares,
scale 0.7 0.7 squares,
scale 0.49 0.49 squares,
scale 0.347 0.347 squares,
scale 0.242 0.242 squares,
color orange stars,
color orange (scale 0.178 0.178 stars),
rotate 11.25 (scale 0.178 0.178 stars),
translate (-50) 0 grid,
rotate 90 (Translate (-50) 0 grid),
rotate 180 (Translate (-50) 0 grid),
rotate 270 (Translate (-50) 0 grid),
color orangered insidegrid,
color orangered2 (rotate 45 insidegrid),
color orangered3 (rotate 22.5 insidegrid),
color orangered3 (rotate 67.5 insidegrid)
]
It's easier if you have separate draw functions for each visual element, but the basic answer is: to animate it just use the animate function and rotate the image components you desire to "move":
import Graphics.Gloss
main = animate (InWindow "Gloss" (700,700) (0,0))
black picture
picture :: Float -> Picture
picture 0 = text "Value cannot be 0"
picture number = scale 6.5 6.5 (color rose $ drawpicture number)
orangered, orangered2, orangered3 :: Color
orangered = makeColor 1.0 0.251 0.0 0.7
orangered2 = makeColor 1.0 0.251 0.0 0.5
orangered3 = makeColor 1.0 0.251 0.0 0.3
intervalsmall = [0,11.25,22.5,33.75,45,56.25,67.5,78.75]
intervalbig = [0,22.5,45,67.5,90,112.5,135,157.5,180,202.5,225,247.5,270,292.5,315,337.5]
xlist = [2,4..50]
ylist = [0,2..48]
squares = pictures[rotate x (line [(-50,0),(0,50),(50,0),(0,-50),(-50,0)]) | x <- intervalsmall]
stars = pictures[rotate x ((pictures [line [(-8.5,0),(0,50),(8.5,0)],line[(0,50),(0,0)]])) | x <- intervalbig]
grid = pictures[line [(0,y),(x,50)] | x <- xlist, y <- ylist, x-y==2]
insidegrid = pictures[
translate 0 (-50) grid,
rotate 90 (translate 0 (-50) grid),
rotate 180 (translate 0 (-50) grid),
rotate 270 (translate 0 (-50) grid)]
rotVal :: Float -> Float
rotVal x = x - (x / (2*pi))
drawpicture :: Float -> Picture
drawpicture number = pictures [
rot $ color red (pictures [circle 50,circle 8.5]),
line [(-50,-50),(-50,50),(50,50),(50,-50),(-50,-50)],
rot $ squares,
rot $ scale 0.7 0.7 squares,
rot $ scale 0.49 0.49 squares,
rot $ scale 0.347 0.347 squares,
rot $ scale 0.242 0.242 squares,
rot $ color orange stars,
rot (color orange (scale 0.178 0.178 stars)),
rot (rotate 11.25 (scale 0.178 0.178 stars)),
translate (-50) 0 grid,
rotate 90 (Translate (-50) 0 grid),
rotate 180 (Translate (-50) 0 grid),
rotate 270 (Translate (-50) 0 grid),
rot $ color orangered insidegrid,
rot $ color orangered2 (rotate 45 insidegrid),
rot $ color orangered3 (rotate 22.5 insidegrid),
rot $ color orangered3 (rotate 67.5 insidegrid)
]
where rot = rotate (rotVal number)
It is too much to write out all for you but you just have to add another argument to your picture function that is a Float and represents time. So display would be replaced by animate. So.
main = animate (InWindow "Gloss" (700,700) (0,0))
black (picture 100)
picture :: Float -> Float -> Picture
picture number time = -- whatever you have to do
You'll have to change your helping drawing functions to take this time param. Let's say you want to rotate the whole think once ever 5 seconds you can just multiply this time coming in and get an angle angle = time*(pi*2/5) then you can use this angle for trig functions to calculate new x and y positions from the center.
I need to draw a batch of scatter charts in matplotlib, and found the speed of matplotlib is slow, then I lineprofile the function, and found the hotspot is fig, ax = plt.subplots(), It costs 56.1% of time to creat a blank figure and axes !!
How to speed it up ? I mean, how can I reuse fig and ax to avoid creating them each time ?
Attach the profile report here (I cut some of the line to make it simple)
Total time: 0.733771 s
Line # Hits Time Per Hit % Time Line Contents
==============================================================
517 #profile
518 def df_scatter(df):
519 ''' draw the scatter plot for Pandas dataframe 'df'
533 '''
536
537 1 75 75.0 0.0 biggest_area = 1000
538 1 117 117.0 0.0 mycm = matplotlib.cm.get_cmap('jet') # 'spectral'
539
541 1 78 78.0 0.0 col_qty = len(df.columns)
543
544 1 1859 1859.0 0.1 x = list(df.ix[:,0].values)
545 1 1258 1258.0 0.0 y = list(df.ix[:,1].values)
551
552 1 1472345 1472345.0 56.1 fig, ax = plt.subplots()
556
557 1 7007 7007.0 0.3 plt.subplots_adjust(left=0.07, right=0.92, bottom=0.1, top=0.95)
558 1 179 179.0 0.0 x_margin, y_margin = (max(x)-min(x))/20, (max(y)-min(y))/20
563
564 1 71 71.0 0.0 if col_qty > 2:
565 1 1602 1602.0 0.1 r = list(df.ix[:,2].values)
566 1 309 309.0 0.0 size_r = np.array(biggest_area)*r/max(r)
585
586 1 34712 34712.0 1.3 sc = plt.scatter(x, y, marker='o', s=size_r, cmap=mycm, alpha=0.65)
587
588 # adding colorbar
589 1 542417 542417.0 20.7 cbaxes = fig.add_axes([0.94, 0.25, 0.02, 0.70])
590 1 165719 165719.0 6.3 cbar = plt.colorbar(sc, cax=cbaxes)
591 1 122 122.0 0.0 cbar.solids.set_edgecolor('face')
595
602 1 1061 1061.0 0.0 plt.figtext(0.94,0.10,"%0.1f"%(max(r)), fontproperties=TEXT_FONT_MEDIUM)
639 1 66 66.0 0.0 return fig
I think that the best way to do it is calling
fig = plt.figure()
ax=fig.add_subplot(111)
from outside of df_scatter. Then, pass it to df_scatter as arguments:
df_scatter(df,fig,ax):
or simply do inside df_scatter:
def df_scatter(df):
fig = plt.gcf()
ax = plt.gca()
after the creation of fig & axis was done.