analyze: plot min/max

This commit is contained in:
Gyu-Ho Lee 2017-02-04 15:15:29 -08:00
parent 37a86b5748
commit e148309de6
No known key found for this signature in database
GPG Key ID: 1DDD39C7EB70C24C
2 changed files with 270 additions and 191 deletions

View File

@ -45,6 +45,163 @@ type PlotConfig struct {
OutputPathList []string `yaml:"output_path_list"`
}
type pair struct {
x dataframe.Column
y dataframe.Column
}
type triplet struct {
x dataframe.Column
minCol dataframe.Column
avgCol dataframe.Column
maxCol dataframe.Column
}
func (all *allAggregatedData) draw(cfg PlotConfig, pairs ...pair) error {
// frame now contains
// AVG-LATENCY-MS-etcd-v3.1-go1.7.4, AVG-LATENCY-MS-zookeeper-r3.4.9-java8, AVG-LATENCY-MS-consul-v0.7.2-go1.7.4
plt, err := plot.New()
if err != nil {
return err
}
plt.Title.Text = fmt.Sprintf("%s, %s", all.title, cfg.YAxis)
plt.X.Label.Text = cfg.XAxis
plt.Y.Label.Text = cfg.YAxis
plt.Legend.Top = true
var ps []plot.Plotter
for i, p := range pairs {
pt, err := points(p.y)
if err != nil {
return err
}
l, err := plotter.NewLine(pt)
if err != nil {
return err
}
l.Color = getRGB(all.headerToLegend[p.y.Header()], i)
l.Dashes = plotutil.Dashes(i)
ps = append(ps, l)
plt.Legend.Add(all.headerToLegend[p.y.Header()], l)
}
plt.Add(ps...)
for _, outputPath := range cfg.OutputPathList {
if err = plt.Save(plotWidth, plotHeight, outputPath); err != nil {
return err
}
}
return nil
}
func (all *allAggregatedData) drawXY(cfg PlotConfig, pairs ...pair) error {
// frame now contains
// KEYS-DB-TAG-X, AVG-LATENCY-MS-DB-TAG-Y, ...
plt, err := plot.New()
if err != nil {
return err
}
plt.Title.Text = fmt.Sprintf("%s, %s", all.title, cfg.YAxis)
plt.X.Label.Text = cfg.XAxis
plt.Y.Label.Text = cfg.YAxis
plt.Legend.Top = true
var ps []plot.Plotter
for i, p := range pairs {
pt, err := pointsXY(p.x, p.y)
if err != nil {
return err
}
l, err := plotter.NewLine(pt)
if err != nil {
return err
}
l.Color = getRGB(all.headerToLegend[p.y.Header()], i)
l.Dashes = plotutil.Dashes(i)
ps = append(ps, l)
plt.Legend.Add(all.headerToLegend[p.y.Header()], l)
}
plt.Add(ps...)
for _, outputPath := range cfg.OutputPathList {
if err = plt.Save(plotWidth, plotHeight, outputPath); err != nil {
return err
}
}
return nil
}
func (all *allAggregatedData) drawXYWithErrorPoints(cfg PlotConfig, triplets ...triplet) error {
// frame now contains
// KEYS-DB-TAG-X, MIN-LATENCY-MS-DB-TAG-Y, AVG-LATENCY-MS-DB-TAG-Y, MAX-LATENCY-MS-DB-TAG-Y, ...
plt, err := plot.New()
if err != nil {
return err
}
plt.Title.Text = fmt.Sprintf("%s, %s", all.title, cfg.YAxis)
plt.X.Label.Text = cfg.XAxis
plt.Y.Label.Text = cfg.YAxis
plt.Legend.Top = true
var ps []plot.Plotter
for i, triplet := range triplets {
{
pt, err := pointsXY(triplet.x, triplet.minCol)
if err != nil {
return err
}
l, err := plotter.NewLine(pt)
if err != nil {
return err
}
l.Color = getRGBII(all.headerToLegend[triplet.avgCol.Header()], i)
l.Dashes = plotutil.Dashes(i)
ps = append(ps, l)
plt.Legend.Add(all.headerToLegend[triplet.avgCol.Header()]+" MIN", l)
}
{
pt, err := pointsXY(triplet.x, triplet.avgCol)
if err != nil {
return err
}
l, err := plotter.NewLine(pt)
if err != nil {
return err
}
l.Color = getRGB(all.headerToLegend[triplet.avgCol.Header()], i)
l.Dashes = plotutil.Dashes(i)
ps = append(ps, l)
plt.Legend.Add(all.headerToLegend[triplet.avgCol.Header()], l)
}
{
pt, err := pointsXY(triplet.x, triplet.maxCol)
if err != nil {
return err
}
l, err := plotter.NewLine(pt)
if err != nil {
return err
}
l.Color = getRGBIII(all.headerToLegend[triplet.avgCol.Header()], i)
l.Dashes = plotutil.Dashes(i)
ps = append(ps, l)
plt.Legend.Add(all.headerToLegend[triplet.avgCol.Header()]+" MAX", l)
}
}
plt.Add(ps...)
for _, outputPath := range cfg.OutputPathList {
if err = plt.Save(plotWidth, plotHeight, outputPath); err != nil {
return err
}
}
return nil
}
func points(col dataframe.Column) (plotter.XYs, error) {
bv, ok := col.BackNonNil()
if !ok {
@ -67,48 +224,6 @@ func points(col dataframe.Column) (plotter.XYs, error) {
return pts, nil
}
func (all *allAggregatedData) draw(
cfg PlotConfig,
cols ...dataframe.Column,
) error {
// frame now contains
// AVG-LATENCY-MS-etcd-v3.1-go1.7.4, AVG-LATENCY-MS-zookeeper-r3.4.9-java8, AVG-LATENCY-MS-consul-v0.7.2-go1.7.4
pl, err := plot.New()
if err != nil {
return err
}
pl.Title.Text = fmt.Sprintf("%s, %s", all.title, cfg.YAxis)
pl.X.Label.Text = cfg.XAxis
pl.Y.Label.Text = cfg.YAxis
pl.Legend.Top = true
var ps []plot.Plotter
for i, col := range cols {
pt, err := points(col)
if err != nil {
return err
}
l, err := plotter.NewLine(pt)
if err != nil {
return err
}
l.Color = getRGB(all.headerToLegend[col.Header()], i)
l.Dashes = plotutil.Dashes(i)
ps = append(ps, l)
pl.Legend.Add(all.headerToLegend[col.Header()], l)
}
pl.Add(ps...)
for _, outputPath := range cfg.OutputPathList {
if err = pl.Save(plotWidth, plotHeight, outputPath); err != nil {
return err
}
}
return nil
}
func pointsXY(colX, colY dataframe.Column) (plotter.XYs, error) {
bv, ok := colX.BackNonNil()
if !ok {
@ -138,106 +253,6 @@ func pointsXY(colX, colY dataframe.Column) (plotter.XYs, error) {
return pts, nil
}
func (all *allAggregatedData) drawXY(
cfg PlotConfig,
cols ...dataframe.Column,
) error {
if len(cols)%2 != 0 {
return fmt.Errorf("expected even number of columns (got %d columns)", len(cols))
}
// frame now contains
// KEYS-DB-TAG-X, AVG-LATENCY-MS-DB-TAG-Y, ...
pl, err := plot.New()
if err != nil {
return err
}
pl.Title.Text = fmt.Sprintf("%s, %s", all.title, cfg.YAxis)
pl.X.Label.Text = cfg.XAxis
pl.Y.Label.Text = cfg.YAxis
pl.Legend.Top = true
var ps []plot.Plotter
for i := 0; i < len(cols)-1; i += 2 {
colX := cols[i]
colY := cols[i+1]
pt, err := pointsXY(colX, colY)
if err != nil {
return err
}
l, err := plotter.NewLine(pt)
if err != nil {
return err
}
l.Color = getRGB(all.headerToLegend[colY.Header()], i)
l.Dashes = plotutil.Dashes(i)
ps = append(ps, l)
pl.Legend.Add(all.headerToLegend[colY.Header()], l)
}
pl.Add(ps...)
for _, outputPath := range cfg.OutputPathList {
if err = pl.Save(plotWidth, plotHeight, outputPath); err != nil {
return err
}
}
return nil
}
func (all *allAggregatedData) drawXYWithErrorBars(
cfg PlotConfig,
cols ...dataframe.Column,
) error {
if len(cols)%2 != 0 {
return fmt.Errorf("expected even number of columns (got %d columns)", len(cols))
}
// frame now contains
// KEYS-DB-TAG-X, MIN-LATENCY-MS-DB-TAG-Y, AVG-LATENCY-MS-DB-TAG-Y, MAX-LATENCY-MS-DB-TAG-Y, ...
pl, err := plot.New()
if err != nil {
return err
}
pl.Title.Text = fmt.Sprintf("%s, %s", all.title, cfg.YAxis)
pl.X.Label.Text = cfg.XAxis
pl.Y.Label.Text = cfg.YAxis
pl.Legend.Top = true
var ps []plot.Plotter
for i := 0; i < len(cols)-1; i += 2 {
colX := cols[i]
colY := cols[i+1]
pt, err := pointsXY(colX, colY)
if err != nil {
return err
}
l, err := plotter.NewLine(pt)
if err != nil {
return err
}
l.Color = getRGB(all.headerToLegend[colY.Header()], i)
l.Dashes = plotutil.Dashes(i)
ps = append(ps, l)
pl.Legend.Add(all.headerToLegend[colY.Header()], l)
}
pl.Add(ps...)
for _, outputPath := range cfg.OutputPathList {
if err = pl.Save(plotWidth, plotHeight, outputPath); err != nil {
return err
}
}
return nil
}
func getRGB(legend string, i int) color.Color {
tag := makeTag(legend)
if strings.HasPrefix(tag, "etcd") {
@ -257,3 +272,43 @@ func getRGB(legend string, i int) color.Color {
}
return plotutil.Color(i)
}
func getRGBII(legend string, i int) color.Color {
tag := makeTag(legend)
if strings.HasPrefix(tag, "etcd") {
return color.RGBA{37, 29, 191, 255} // deep-blue
}
if strings.HasPrefix(tag, "zookeeper") {
return color.RGBA{7, 64, 35, 255} // deep-green
}
if strings.HasPrefix(tag, "consul") {
return color.RGBA{212, 8, 46, 255} // deep-red
}
if strings.HasPrefix(tag, "zetcd") {
return color.RGBA{229, 255, 0, 255} // deep-yellow
}
if strings.HasPrefix(tag, "cetcd") {
return color.RGBA{255, 0, 251, 255} // deep-purple
}
return plotutil.Color(i)
}
func getRGBIII(legend string, i int) color.Color {
tag := makeTag(legend)
if strings.HasPrefix(tag, "etcd") {
return color.RGBA{129, 212, 247, 255} // light-blue
}
if strings.HasPrefix(tag, "zookeeper") {
return color.RGBA{129, 247, 152, 255} // light-green
}
if strings.HasPrefix(tag, "consul") {
return color.RGBA{247, 156, 156, 255} // light-red
}
if strings.HasPrefix(tag, "zetcd") {
return color.RGBA{245, 247, 166, 255} // light-yellow
}
if strings.HasPrefix(tag, "cetcd") {
return color.RGBA{247, 166, 238, 255} // light-purple
}
return plotutil.Color(i)
}

View File

@ -483,21 +483,23 @@ func do(configPath string) error {
allLatencyFrameCfg.OutputPathList[0] = filepath.Join(filepath.Dir(cfg.PlotList[0].OutputPathList[0]), "AVG-LATENCY-MS-BY-KEY.svg")
allLatencyFrameCfg.OutputPathList[1] = filepath.Join(filepath.Dir(cfg.PlotList[0].OutputPathList[0]), "AVG-LATENCY-MS-BY-KEY.png")
plog.Printf("plotting %v", allLatencyFrameCfg.OutputPathList)
var allLatencyFrameCols []dataframe.Column
for _, col := range allLatencyFrame.Columns() {
switch {
case strings.HasPrefix(col.Header(), "KEYS-"):
allLatencyFrameCols = append(allLatencyFrameCols, col) // x-axis
case strings.HasPrefix(col.Header(), "AVG-LATENCY-MS-"):
allLatencyFrameCols = append(allLatencyFrameCols, col) // y-axis
}
var pairs []pair
allCols := allLatencyFrame.Columns()
for i := 0; i < len(allCols)-3; i += 4 {
pairs = append(pairs, pair{
x: allCols[i], // x
y: allCols[i+2], // avg
})
}
if err = all.drawXY(allLatencyFrameCfg, allLatencyFrameCols...); err != nil {
if err = all.drawXY(allLatencyFrameCfg, pairs...); err != nil {
return err
}
newCSV := dataframe.New()
for _, col := range allLatencyFrameCols {
if err = newCSV.AddColumn(col); err != nil {
for _, p := range pairs {
if err = newCSV.AddColumn(p.x); err != nil {
return err
}
if err = newCSV.AddColumn(p.y); err != nil {
return err
}
}
@ -507,8 +509,7 @@ func do(configPath string) error {
}
}
{
// TODO: draw with error bar
// with error points
allLatencyFrameCfg := PlotConfig{
Column: "AVG-LATENCY-MS",
XAxis: "Cumulative Number of Keys",
@ -518,21 +519,31 @@ func do(configPath string) error {
allLatencyFrameCfg.OutputPathList[0] = filepath.Join(filepath.Dir(cfg.PlotList[0].OutputPathList[0]), "AVG-LATENCY-MS-BY-KEY-ERROR-POINTS.svg")
allLatencyFrameCfg.OutputPathList[1] = filepath.Join(filepath.Dir(cfg.PlotList[0].OutputPathList[0]), "AVG-LATENCY-MS-BY-KEY-ERROR-POINTS.png")
plog.Printf("plotting %v", allLatencyFrameCfg.OutputPathList)
var allLatencyFrameCols []dataframe.Column
for _, col := range allLatencyFrame.Columns() {
switch {
case strings.HasPrefix(col.Header(), "KEYS-"):
allLatencyFrameCols = append(allLatencyFrameCols, col) // x-axis
case strings.HasPrefix(col.Header(), "AVG-LATENCY-MS-"):
allLatencyFrameCols = append(allLatencyFrameCols, col) // y-axis
}
var triplets []triplet
allCols := allLatencyFrame.Columns()
for i := 0; i < len(allCols)-3; i += 4 {
triplets = append(triplets, triplet{
x: allCols[i],
minCol: allCols[i+1],
avgCol: allCols[i+2],
maxCol: allCols[i+3],
})
}
if err = all.drawXY(allLatencyFrameCfg, allLatencyFrameCols...); err != nil {
if err = all.drawXYWithErrorPoints(allLatencyFrameCfg, triplets...); err != nil {
return err
}
newCSV := dataframe.New()
for _, col := range allLatencyFrameCols {
if err = newCSV.AddColumn(col); err != nil {
for _, tri := range triplets {
if err = newCSV.AddColumn(tri.x); err != nil {
return err
}
if err = newCSV.AddColumn(tri.minCol); err != nil {
return err
}
if err = newCSV.AddColumn(tri.avgCol); err != nil {
return err
}
if err = newCSV.AddColumn(tri.maxCol); err != nil {
return err
}
}
@ -599,21 +610,23 @@ func do(configPath string) error {
allMemoryFrameCfg.OutputPathList[0] = filepath.Join(filepath.Dir(cfg.PlotList[0].OutputPathList[0]), "AVG-VMRSS-MB-BY-KEY.svg")
allMemoryFrameCfg.OutputPathList[1] = filepath.Join(filepath.Dir(cfg.PlotList[0].OutputPathList[0]), "AVG-VMRSS-MB-BY-KEY.png")
plog.Printf("plotting %v", allMemoryFrameCfg.OutputPathList)
var allMemoryFrameCols []dataframe.Column
for _, col := range allMemoryFrame.Columns() {
switch {
case strings.HasPrefix(col.Header(), "KEYS-"):
allMemoryFrameCols = append(allMemoryFrameCols, col) // x-axis
case strings.HasPrefix(col.Header(), "AVG-VMRSS-MB-"):
allMemoryFrameCols = append(allMemoryFrameCols, col) // y-axis
}
var pairs []pair
allCols := allMemoryFrame.Columns()
for i := 0; i < len(allCols)-3; i += 4 {
pairs = append(pairs, pair{
x: allCols[i], // x
y: allCols[i+2], // avg
})
}
if err = all.drawXY(allMemoryFrameCfg, allMemoryFrameCols...); err != nil {
if err = all.drawXY(allMemoryFrameCfg, pairs...); err != nil {
return err
}
newCSV := dataframe.New()
for _, col := range allMemoryFrameCols {
if err = newCSV.AddColumn(col); err != nil {
for _, p := range pairs {
if err = newCSV.AddColumn(p.x); err != nil {
return err
}
if err = newCSV.AddColumn(p.y); err != nil {
return err
}
}
@ -623,8 +636,7 @@ func do(configPath string) error {
}
}
{
// TODO: draw with error bar
// with error points
allMemoryFrameCfg := PlotConfig{
Column: "AVG-VMRSS-MB",
XAxis: "Cumulative Number of Keys",
@ -634,21 +646,31 @@ func do(configPath string) error {
allMemoryFrameCfg.OutputPathList[0] = filepath.Join(filepath.Dir(cfg.PlotList[0].OutputPathList[0]), "AVG-VMRSS-MB-BY-KEY-ERROR-POINTS.svg")
allMemoryFrameCfg.OutputPathList[1] = filepath.Join(filepath.Dir(cfg.PlotList[0].OutputPathList[0]), "AVG-VMRSS-MB-BY-KEY-ERROR-POINTS.png")
plog.Printf("plotting %v", allMemoryFrameCfg.OutputPathList)
var allMemoryFrameCols []dataframe.Column
for _, col := range allMemoryFrame.Columns() {
switch {
case strings.HasPrefix(col.Header(), "KEYS-"):
allMemoryFrameCols = append(allMemoryFrameCols, col) // x-axis
case strings.HasPrefix(col.Header(), "AVG-VMRSS-MB-"):
allMemoryFrameCols = append(allMemoryFrameCols, col) // y-axis
}
var triplets []triplet
allCols := allMemoryFrame.Columns()
for i := 0; i < len(allCols)-3; i += 4 {
triplets = append(triplets, triplet{
x: allCols[i],
minCol: allCols[i+1],
avgCol: allCols[i+2],
maxCol: allCols[i+3],
})
}
if err = all.drawXY(allMemoryFrameCfg, allMemoryFrameCols...); err != nil {
if err = all.drawXYWithErrorPoints(allMemoryFrameCfg, triplets...); err != nil {
return err
}
newCSV := dataframe.New()
for _, col := range allMemoryFrameCols {
if err = newCSV.AddColumn(col); err != nil {
for _, tri := range triplets {
if err = newCSV.AddColumn(tri.x); err != nil {
return err
}
if err = newCSV.AddColumn(tri.minCol); err != nil {
return err
}
if err = newCSV.AddColumn(tri.avgCol); err != nil {
return err
}
if err = newCSV.AddColumn(tri.maxCol); err != nil {
return err
}
}
@ -662,6 +684,7 @@ func do(configPath string) error {
for _, plotConfig := range cfg.PlotList {
plog.Printf("plotting %q", plotConfig.Column)
var clientNumColumns []dataframe.Column
var pairs []pair
var dataColumns []dataframe.Column
for i, ad := range all.data {
tag := all.databaseTags[i]
@ -678,9 +701,10 @@ func do(configPath string) error {
return err
}
col.UpdateHeader(makeHeader(plotConfig.Column, tag))
pairs = append(pairs, pair{y: col})
dataColumns = append(dataColumns, col)
}
if err = all.draw(plotConfig, dataColumns...); err != nil {
if err = all.draw(plotConfig, pairs...); err != nil {
return err
}