天泣記

2010-09-12 (Sun)

#1

github の puhch card みたいなのを自分で生成したいと思って cairo を使って描いてみた。

changelog.png

ChangeLog が元データなので、日本時間である。

また、円の面積が ChangeLog の項目数に比例する。

stat-changelog.rb:

#!/usr/bin/ruby1.8

# usage:
# ./stat-changelog.rb ruby/{ChangeLog,doc/ChangeLog-1.9.3,doc/ChangeLog-1.8.0}

require 'time'

WDAYS = %w[Sun Mon Tue Wed Thu Fri Sat]
MONTHS = %w[Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec]

h = Hash.new(0)
ARGF.each {|line|
  if /\A((?:#{Regexp.union WDAYS})\s+(#{Regexp.union MONTHS})\s+\d+\s+\d\d:\d\d:\d\d\s+\d+)/o =~ line
    t = Time.parse($1)
    k = [t.wday, t.hour]
    h[k] += 1
  end
}

max = 0
h.each_value {|n|
  max = n if max < n
}
if max == 0
  puts 'no data'
  exit
end

require 'cairo'
require 'pango'

format = Cairo::FORMAT_ARGB32

radius = 20
diameter = radius * 2
width = diameter * (1+24)
height = diameter * (1+7)

surface = Cairo::ImageSurface.new(format, width, height)
context = Cairo::Context.new(surface)

# background
context.set_source_rgb(1, 1, 1) # white
context.rectangle(0, 0, width, height)
context.fill

context.set_source_rgb(0, 0, 0) # black

hour_layouts = []
0.upto(23) {|hour|
  layout = context.create_pango_layout
  layout.text = "%02d" % hour
  layout.width = diameter * Pango::SCALE
  layout.alignment = Pango::ALIGN_CENTER
  hour_layouts << layout
}
max_height = hour_layouts.map {|layout| layout.size[1] }.max
hour_layouts.each_with_index {|layout, hour|
  context.save {
    context.translate((1+hour) * diameter, radius - max_height / Pango::SCALE / 2)
    context.show_pango_layout(layout)
  }
}

wday_layouts = []
0.upto(6) {|wday|
  layout = context.create_pango_layout
  layout.text = WDAYS[wday]
  layout.width = diameter * Pango::SCALE
  wday_layouts << layout
}
max_width = wday_layouts.map {|layout| layout.size[0] }.max
max_height = wday_layouts.map {|layout| layout.size[1] }.max
wday_layouts.each_with_index {|layout, wday|
  context.save {
    context.translate(radius - max_width / Pango::SCALE / 2, (1+wday) * diameter + radius - max_height / Pango::SCALE / 2)
    context.show_pango_layout(layout)
  }
}
0.upto(6) {|wday|
  0.upto(23) {|hour|
    n = h[[wday, hour]]
    r = Math.sqrt(n) / Math.sqrt(max) * radius
    context.arc((1+hour) * diameter + radius, (1+wday) * diameter + radius, r, 0, 2 * Math::PI)
    context.fill
  }
}

surface.write_to_png("changelog.png")
system("feh changelog.png")
#2

Debian Bug #596492 - The unit of the amount of CPU time for RLIMIT_RTTIME

2010-09-18 (Sat)

#1

R の ggplot2 というのが良いらしいと聞いたので試してみる。(データは Wikipedia から)

bmi-gnu_r-ggplot.png

bmi-gnu_r-ggplot.R:

library(ggplot2)

names <- c("唯", "澪", "律", "紬", "梓", "さわ子", "和", "憂")
heights <- c(156, 160, 154, 157, 150, 165, 158, 154)
weights <- c(50, 54, 48, 53, 46, 56, 52, 50)

data <- data.frame(name=names, height=heights, weight=weights)

bmi <- function(b) function(w) sqrt(w/b)*100

x = seq(40,60,1)

p <- ggplot() + xlim(40,60) + ylim(140,180)
p <- p + geom_text(aes(x=data$weight, y=data$height, label=data$name))
p <- p + xlab("体重[kg]") + ylab("身長[cm]")
p <- p + geom_line(aes(x=x, y=bmi(18.5)(x)))
p <- p + geom_line(aes(x=x, y=bmi(25)(x)))
p <- p + geom_line(aes(x=x, y=bmi(30)(x)))
p <- p + geom_line(aes(x=x, y=bmi(40)(x)))
p <- p + geom_text(aes(x=45,y=170,label="低体重"))
p <- p + geom_text(aes(x=58,y=170,label="普通"))
p <- p + geom_text(aes(x=58,y=145,label="前肥満"))
print(p)

みなさん普通で健康的ですな。

それはそれとして、曲線を端まで描く方法がわからない。

#2

coord_cartesian() を使えばいいのか。

bmi-gnu_r-ggplot-2.png

bmi-gnu_r-ggplot-2.R:

library(ggplot2)

names <- c("唯", "澪", "律", "紬", "梓", "さわ子", "和", "憂")
heights <- c(156, 160, 154, 157, 150, 165, 158, 154)
weights <- c(50, 54, 48, 53, 46, 56, 52, 50)

data <- data.frame(name=names, height=heights, weight=weights)

bmi <- function(b) function(w) sqrt(w/b)*100

xx = seq(40,60,1)

p <- ggplot() 
p <- p + coord_cartesian(xlim=c(40,60), ylim=c(140,170))
p <- p + scale_y_continuous(breaks=seq(140,180,by=10))
p <- p + geom_ribbon(aes(x=xx, ymin=bmi(18.5)(xx), ymax=180), fill="skyblue", alpha=0.5)
p <- p + geom_ribbon(aes(x=xx, ymin=bmi(25)(xx), ymax=bmi(18.5)(xx)), fill="lightgreen", alpha=0.5)
p <- p + geom_ribbon(aes(x=xx, ymin=bmi(30)(xx), ymax=bmi(25)(xx)), fill="yellow3", alpha=0.5)
p <- p + geom_ribbon(aes(x=xx, ymin=130, ymax=bmi(30)(xx)), fill="orangered", alpha=0.5)
p <- p + geom_text(aes(x=data$weight, y=data$height, label=data$name))
p <- p + xlab("体重[kg]") + ylab("身長[cm]")
p <- p + geom_line(aes(x=xx, y=bmi(18.5)(xx)))
p <- p + geom_line(aes(x=xx, y=bmi(25)(xx)))
p <- p + geom_line(aes(x=xx, y=bmi(30)(xx)))
p <- p + geom_line(aes(x=xx, y=bmi(40)(xx)))
p <- p + geom_text(aes(x=44,y=163,label="低体重(BMI: 〜18.5)"))
p <- p + geom_text(aes(x=44,y=143,label="普通(BMI: 18.5〜25)"))
p <- p + geom_text(aes(x=56,y=143,label="前肥満(BMI: 25〜30)"))
print(p)

2010-09-19 (Sun)

#1

ぐらでーしょん

bmi-gnu_r-ggplot-3.png

bmi-gnu_r-ggplot-3.R:

library(ggplot2)

names <- c("唯", "澪", "律", "紬", "梓", "さわ子", "和", "憂")
heights <- c(156, 160, 154, 157, 150, 165, 158, 154)
weights <- c(50, 54, 48, 53, 46, 56, 52, 50)

data <- data.frame(name=names, height=heights, weight=weights)

bmi <- function(b) function(w) sqrt(w/b)*100

xx <- seq(40,60,0.2)
yy <- seq(140,170,0.2)

bmi_w <- rep(xx, length(yy))
bmi_h <- rep(yy, rep(length(xx), length(yy)))
bmi_bmi <- bmi_w / (bmi_h/100)^2
bmi_table <- data.frame(w=bmi_w, h=bmi_h, BMI=bmi_bmi)

p <- ggplot()
p <- p + coord_cartesian(xlim=c(40,60), ylim=c(140,170))
p <- p + scale_y_continuous(breaks=seq(140,180,by=10))
p <- p + scale_fill_gradient2(low="blue", mid="green", high="red", midpoint=22)
p <- p + geom_tile(data=bmi_table, aes(x=w, y=h, z=BMI, fill=BMI, alpha=0.7))
p <- p + geom_text(aes(x=data$weight, y=data$height, label=data$name))
p <- p + xlab("体重[kg]") + ylab("身長[cm]")
p <- p + geom_line(aes(x=xx, y=bmi(18.5)(xx)))
p <- p + geom_line(aes(x=xx, y=bmi(25)(xx)))
p <- p + geom_line(aes(x=xx, y=bmi(30)(xx)))
p <- p + geom_line(aes(x=xx, y=bmi(40)(xx)))
p <- p + geom_text(aes(x=44,y=163,label="低体重(BMI: 〜18.5)"))
p <- p + geom_text(aes(x=44,y=143,label="普通(BMI: 18.5〜25)"))
p <- p + geom_text(aes(x=56,y=143,label="前肥満(BMI: 25〜30)"))
print(p)

凡例に alpha の 0.7 が出てくるのはわからない。


[latest]


田中哲