Skip to content

Commit 6e4f5c5

Browse files
committed
plot: add a flag --scale
1 parent 72c49c5 commit 6e4f5c5

9 files changed

Lines changed: 93 additions & 34 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,16 @@
1919
- do not show progress.
2020
- `csvtk fix-quotes`:
2121
- new flag `-b, --buffer-size`.
22+
- `csvtk plot`:
23+
- new flag `--scale` for scaling the image width/height, tick, axes, line/point and font sizes proportionally, adviced by @tseemann.
2224
- `csvtk plot line`:
2325
- only add legend for more than one group. [#279](https://github.com/shenwei356/csvtk/issues/279)
2426
- sort points by X for plotting lines. [#280](https://github.com/shenwei356/csvtk/issues/280)
27+
- `csvtk hist`:
28+
- new flags: `--line-width`.
29+
- `csvtk box`:
30+
- plots of different groups have different colors now.
31+
- new flags: `--line-width`, `--point-size`, and `color-index`.
2532
- [csvtk v0.30.0](https://github.com/shenwei356/csvtk/releases/tag/v0.30.0)
2633
[![Github Releases (by Release)](https://img.shields.io/github/downloads/shenwei356/csvtk/v0.30.0/total.svg)](https://github.com/shenwei356/csvtk/releases/tag/v0.30.0)
2734
- `csvtk`:

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ Examples
401401
group information is the "Group" column.
402402

403403
csvtk -t plot box testdata/grouped_data.tsv.gz -g "Group" \
404-
-f "GC Content" --width 3 | display
404+
-f "GC Content" --width 3 --title "Box plot" | display
405405

406406
![boxplot.png](testdata/figures/boxplot.png)
407407

csvtk/cmd/box.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"github.com/spf13/cobra"
3333
"gonum.org/v1/plot"
3434
"gonum.org/v1/plot/plotter"
35+
"gonum.org/v1/plot/plotutil"
3536
"gonum.org/v1/plot/vg"
3637
)
3738

@@ -67,6 +68,14 @@ Notes:
6768
if skipNA && len(naValues) == 0 {
6869
log.Errorf("the value of --na-values should not be empty when using --skip-na")
6970
}
71+
72+
lineWidth := vg.Points(getFlagPositiveFloat64(cmd, "line-width") * plotConfig.scale)
73+
pointSize := vg.Length(getFlagPositiveFloat64(cmd, "point-size") * plotConfig.scale)
74+
colorIndex := getFlagPositiveInt(cmd, "color-index")
75+
if colorIndex > 7 {
76+
checkError(fmt.Errorf("unsupported color index"))
77+
}
78+
7079
naMap := make(map[string]interface{}, len(naValues))
7180
for _, na := range naValues {
7281
naMap[strings.ToLower(na)] = struct{}{}
@@ -148,6 +157,7 @@ Notes:
148157
}
149158

150159
groupNames := make([]string, len(groupOrders))
160+
j := colorIndex - 1
151161
for i, group := range groupOrders {
152162
groupNames[i] = group.Key
153163
b, err := plotter.NewBoxPlot(w, float64(i), groups[group.Key])
@@ -156,6 +166,20 @@ Notes:
156166
b.Horizontal = true
157167
}
158168
p.Add(b)
169+
170+
b.BoxStyle.Color = plotutil.Color(j)
171+
b.BoxStyle.Width = lineWidth
172+
173+
b.MedianStyle.Color = plotutil.Color(j)
174+
b.MedianStyle.Width = lineWidth
175+
176+
b.WhiskerStyle.Color = plotutil.Color(j)
177+
b.WhiskerStyle.Width = lineWidth
178+
179+
b.GlyphStyle.Color = plotutil.Color(j)
180+
b.GlyphStyle.Radius = pointSize
181+
182+
j++
159183
}
160184

161185
if !horiz {
@@ -236,4 +260,8 @@ func init() {
236260

237261
boxCmd.Flags().Float64P("box-width", "", 0, "box width")
238262
boxCmd.Flags().BoolP("horiz", "", false, "horize box plot")
263+
264+
boxCmd.Flags().Float64P("line-width", "", 1.5, "line width")
265+
boxCmd.Flags().Float64P("point-size", "", 3, "point size")
266+
boxCmd.Flags().IntP("color-index", "", 1, `color index, 1-7`)
239267
}

csvtk/cmd/hist.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ Notes:
5656
config := getConfigs(cmd)
5757
plotConfig := getPlotConfigs(cmd)
5858

59+
lineWidth := vg.Points(getFlagPositiveFloat64(cmd, "line-width") * plotConfig.scale)
60+
5961
files := getFileListFromArgsAndFile(cmd, args, true, "infile-list", true)
6062
if len(files) > 1 {
6163
checkError(fmt.Errorf("no more than one file should be given"))
@@ -137,6 +139,7 @@ Notes:
137139

138140
// h.Normalize(1)
139141
h.FillColor = plotutil.Color(colorIndex - 1)
142+
h.LineStyle.Width = lineWidth
140143
p.Add(h)
141144

142145
p.Title.Text = plotConfig.title
@@ -193,4 +196,6 @@ func init() {
193196
histCmd.Flags().IntP("color-index", "", 1, `color index, 1-7`)
194197
histCmd.Flags().BoolP("percentiles", "", false, `calculate percentiles`)
195198

199+
histCmd.Flags().Float64P("line-width", "", 1, "line width")
200+
196201
}

csvtk/cmd/line.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ Notes:
6262
}
6363
runtime.GOMAXPROCS(config.NumCPUs)
6464

65-
lineWidth := vg.Points(getFlagPositiveFloat64(cmd, "line-width"))
66-
pointSize := vg.Length(getFlagPositiveFloat64(cmd, "point-size"))
6765
scatter := getFlagBool(cmd, "scatter")
66+
lineWidth := vg.Points(getFlagPositiveFloat64(cmd, "line-width") * plotConfig.scale)
67+
pointSize := vg.Length(getFlagPositiveFloat64(cmd, "point-size") * plotConfig.scale)
6868
colorIndex := getFlagPositiveInt(cmd, "color-index")
6969
if colorIndex > 7 {
7070
checkError(fmt.Errorf("unsupported color index"))
@@ -206,6 +206,7 @@ Notes:
206206
if !scatter {
207207
lines, points, err := plotter.NewLinePoints(v)
208208
checkError(err)
209+
fmt.Fprintln(os.Stderr, i)
209210
lines.Color = plotutil.Color(i)
210211
lines.LineStyle.Dashes = plotutil.Dashes(i)
211212
lines.LineStyle.Width = lineWidth

csvtk/cmd/plot.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ func init() {
7272
plotCmd.PersistentFlags().Float64P("axis-width", "", 1.5, "axis width")
7373
plotCmd.PersistentFlags().Float64P("tick-width", "", 1.5, "axis tick width")
7474
plotCmd.PersistentFlags().IntP("tick-label-size", "", 12, "tick label font size")
75+
plotCmd.PersistentFlags().Float64P("scale", "", 1, "scale the image width/height, tick, axes, line/point and font sizes proportionally")
7576

7677
plotCmd.PersistentFlags().StringP("format", "", "png", `image format for stdout when flag -o/--out-file not given. available values: eps, jpg|jpeg, pdf, png, svg, and tif|tiff.`)
7778

@@ -105,13 +106,18 @@ func getPlotConfigs(cmd *cobra.Command) *plotConfigs {
105106
}
106107

107108
config.title = getFlagString(cmd, "title")
108-
config.titleSize = vg.Length(getFlagPositiveInt(cmd, "title-size"))
109-
config.labelSize = vg.Length(getFlagPositiveInt(cmd, "label-size"))
110-
config.width = vg.Length(getFlagPositiveFloat64(cmd, "width"))
111-
config.height = vg.Length(getFlagPositiveFloat64(cmd, "height"))
112-
config.axisWidth = vg.Length(getFlagPositiveFloat64(cmd, "axis-width"))
113-
config.tickWidth = vg.Length(getFlagPositiveFloat64(cmd, "tick-width"))
114-
config.tickLabelSize = vg.Length(getFlagPositiveInt(cmd, "tick-label-size"))
109+
110+
scale := getFlagPositiveFloat64(cmd, "scale")
111+
config.scale = scale
112+
113+
config.titleSize = vg.Length(int(float64(getFlagPositiveInt(cmd, "title-size")) * scale))
114+
config.labelSize = vg.Length(int(float64(getFlagPositiveInt(cmd, "label-size")) * scale))
115+
config.width = vg.Length(getFlagPositiveFloat64(cmd, "width") * scale)
116+
config.height = vg.Length(getFlagPositiveFloat64(cmd, "height") * scale)
117+
config.axisWidth = vg.Length(getFlagPositiveFloat64(cmd, "axis-width") * scale)
118+
config.tickWidth = vg.Length(getFlagPositiveFloat64(cmd, "tick-width") * scale)
119+
config.tickLabelSize = vg.Length(int(float64(getFlagPositiveInt(cmd, "tick-label-size")) * scale))
120+
115121
config.xlab = getFlagString(cmd, "xlab")
116122
config.ylab = getFlagString(cmd, "ylab")
117123

@@ -161,6 +167,7 @@ type plotConfigs struct {
161167
title, xlab, ylab string
162168
titleSize, labelSize, tickLabelSize vg.Length
163169
width, height, axisWidth, tickWidth vg.Length
170+
scale float64
164171
xmin, xmax, ymin, ymax float64
165172
xminStr, xmaxStr, yminStr, ymaxStr string
166173
format string

doc/docs/usage.md

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4180,27 +4180,29 @@ Available Commands:
41804180
line line plot and scatter plot
41814181
41824182
Flags:
4183-
--axis-width float axis width (default 1.5)
4184-
-f, --data-field string column index or column name of data (default "1")
4185-
--format string image format for stdout when flag -o/--out-file not given. available
4186-
values: eps, jpg|jpeg, pdf, png, svg, and tif|tiff. (default "png")
4187-
-g, --group-field string column index or column name of group
4188-
--height float Figure height (default 4.5)
4189-
-h, --help help for plot
4190-
--label-size int label font size (default 14)
4191-
--na-values strings NA values, case ignored (default [,NA,N/A])
4192-
--skip-na skip NA values in --na-values
4183+
--axis-width float axis width (default 1.5)
4184+
-f, --data-field string column index or column name of data (default "1")
4185+
--format string image format for stdout when flag -o/--out-file not given. available
4186+
values: eps, jpg|jpeg, pdf, png, svg, and tif|tiff. (default "png")
4187+
-g, --group-field string column index or column name of group
4188+
--height float Figure height (default 4.5)
4189+
-h, --help help for plot
4190+
--label-size int label font size (default 14)
4191+
--na-values strings NA values, case ignored (default [,NA,N/A])
4192+
--scale float scale the image width/height, tick, axes, line/point and font sizes
4193+
proportionally (default 1)
4194+
--skip-na skip NA values in --na-values
41934195
--tick-label-size int tick label font size (default 12)
4194-
--tick-width float axis tick width (default 1.5)
4195-
--title string Figure title
4196-
--title-size int title font size (default 16)
4197-
--width float Figure width (default 6)
4198-
--x-max string maximum value of X axis
4199-
--x-min string minimum value of X axis
4200-
--xlab string x label text
4201-
--y-max string maximum value of Y axis
4202-
--y-min string minimum value of Y axis
4203-
--ylab string y label text
4196+
--tick-width float axis tick width (default 1.5)
4197+
--title string Figure title
4198+
--title-size int title font size (default 16)
4199+
--width float Figure width (default 6)
4200+
--x-max string maximum value of X axis
4201+
--x-min string minimum value of X axis
4202+
--xlab string x label text
4203+
--y-max string maximum value of Y axis
4204+
--y-min string minimum value of Y axis
4205+
--ylab string y label text
42044206
42054207
```
42064208

@@ -4236,8 +4238,11 @@ Usage:
42364238
csvtk plot hist [flags]
42374239
42384240
Flags:
4239-
--bins int number of bins (default 50)
4240-
--color-index int color index, 1-7 (default 1)
4241+
--bins int number of bins (default 50)
4242+
--color-index int color index, 1-7 (default 1)
4243+
-h, --help help for hist
4244+
--line-width float line width (default 1)
4245+
--percentiles calculate percentiles
42414246
42424247
```
42434248

@@ -4284,8 +4289,12 @@ Usage:
42844289
csvtk plot box [flags]
42854290
42864291
Flags:
4287-
--box-width float box width
4288-
--horiz horize box plot
4292+
--box-width float box width
4293+
--color-index int color index, 1-7 (default 1)
4294+
-h, --help help for box
4295+
--horiz horize box plot
4296+
--line-width float line width (default 1.5)
4297+
--point-size float point size (default 3)
42894298
42904299
```
42914300

@@ -4329,8 +4338,10 @@ Usage:
43294338
csvtk plot line [flags]
43304339
43314340
Flags:
4341+
--color-index int color index, 1-7 (default 1)
43324342
-x, --data-field-x string column index or column name of X for command line
43334343
-y, --data-field-y string column index or column name of Y for command line
4344+
-h, --help help for line
43344345
--legend-left locate legend along the left edge of the plot
43354346
--legend-top locate legend along the top edge of the plot
43364347
--line-width float line width (default 1.5)

testdata/figures/boxplot.png

2.38 KB
Loading

testdata/figures/boxplot2.png

1.44 KB
Loading

0 commit comments

Comments
 (0)