larsmagne / eplot

Emacs library for creating charts
https://lars.ingebrigtsen.no/2024/06/26/a-new-package-for-making-charts-in-emacs-eplot/
102 stars 3 forks source link

eplot is an Emacs package for generating time series charts, plots and bar charts interactively.

This is a work in progress and is probably not very useful generally yet, but here's the documentation so far:

movie-plot.plt

Here's an example...

chart-legend.plt

And here's another.

But let's start from the start. Here's a trivial example, trivial-very-short.plt:

41
42.1
44.7

Then say `M-x eplot' in this buffer, and you'll get this displayed:

trivial-very-short.plt

To tweak the look of the chart, there are three possibilities:

Below, this final method is used in all the examples, because that's convenient when going through lots of different settings in the manual, but I'm guessing most users might want to use one of the two first methods (which can be mixed -- you can do some settings via Transient and some via the Controls buffer).

In most of the examples below, the following header lines are present, and are not included in the code examples:

Layout: compact
Width: 300
Height: 200

By default, eplot uses a more spacious layout, and the width/heights are automatically calculated based on the window size. But for these examples in this manual, it's more convenient to show smaller, more compact charts.

You don't need to have the actual chart data in the .plt file -- instead you can specify the location with a Data: plot header:

Data: data1.txt

chart-simple.plt

This is the basic, default look of that data set.

OK, let's go through all the various options you have to change the look of the charts.

First of all, several different plotting styles are available. The default is the "line" Style.

Style: square

chart-square.plt

Style: triangle
Fill-Color: #c0c0c0

Some styles also take a Fill parameter to specify the fill color.

chart-triangle.plt

Style: rectangle

chart-rectangle.plt

Size: 3
Color: red black green blue brown
Style: impulse

chart-impulse-wide.plt

Style: point

chart-point.plt

Style: cross

chart-cross.plt

Style: circle
Size: 8

chart-circle.plt

That's all the basic plotting styles.

You can have several plots in one chart, with their own styles and colors.

Data: data1.txt

Style: impulse
Color: blue
Data: data2.txt

chart-two-plots.plt

There's a special color spec called "vary", and it results in choosing between some pre-defined legible colors:

Style: circle
Fill-Color: vary
Color: none
Size: 8

chart-circle-colors.plt

The "vary" isn't useful on all plot styles:

Color: vary
Data: data1.txt

chart-segment.plt

You can also specify colors/sizes on a per-data point basis. Here's an excerpt from a plt file that demonstrates that:

Style: circle
Fill-Color: none
41
42.1
42.1
44.1
43.6 # Size: 10, Fill-Color: red
43.6
42.9
43
43.2
44.4
44.5
45.4
45.9
52   # Size: 10, Fill-Color: blue
53

chart-circle-sizes.plt

Bar charts are somewhat special.

Format: bar-chart

Color: vary
33
20
24

chart-bar.plt

Each bar is displayed separately, and the labels on the X axis are displayed in the middle of the bars -- this is quite different from the box plot on the same data set:

Format: normal
Min: 0

Style: square
33
20
24

chart-bar-box.plt

Anyway, the first bar box demonstrated the "vary" color again, but you can specify the colors yourself:

Format: bar-chart

Color: green gray
33 # Label: Apples
20 # Label: Oranges
24 # Label: Appanges

chart-color-list.plt

When it runs out of colors, it starts anew. And another feature demonstrated here is that you can specify the labels on a per-item basis.

You can also have plots with two values per item, and eplot then fills the data in between:

Data-Format: two-values
Style: square
Fill-Color: lightblue
Fill-Border-Color: black
Data: data-between.txt

chart-between2.plt

Mode: dark
Border-Width: 1

Data-Format: two-values
Style: square
Gradient: red black
Data: data-between.txt

chart-between1.plt

This is the same data set, but in "dark mode", and with a gradient between the values. Oh, and a border, because why not.

Data-Column: 2
41     57.551391
42.1    59.88006
42.1    59.88006
...

chart-second-column.plt

It can sometimes be convenient to have several data sets in the same file, but in different columns. You can use the Data-Column header to specify which column to plot.

OK, there's a lot of details about the plot you can specify. Here's an example:

Border-Color: yellow
Border-Width: 3
Frame-Color: red
Surround-Color: green
Background-Color: blue
Grid-Color: black
Chart-Color: white
Title: Title, background and border
Axes-Color: black
Title-Color: red

Data: data1.txt

chart-color.plt

Go wild! But preferably not that wild.

Gradient: black red
Data: data1.txt

chart-gradient1.plt

You can also plot the data using gradients.

Gradient: black red
Style: square
Data: data1.txt

chart-gradient-square.plt

You can put the gradient above the chart instead:

Gradient: black red top-down above
Data: data1.txt

chart-gradient2.plt

Gradient: black red bottom-up
Data: data1.txt

chart-gradient3.plt

You can specify the direction -- this one is basically just swapping the order of the colors.

Gradient: black red right-left above
Data: data1.txt

chart-gradient4.plt

But also right-left...

Gradient: black red left-right below
Data: data1.txt

chart-gradient6.plt

... and left-right.

Gradient: black red bottom-up above
Data: data1.txt

Gradient: black red top-down below
Data: data1.txt

chart-gradient5.plt

And below the plot.

Gradient: black red left-right above
Data: data1.txt

chart-two-gradient1.plt

You can plot the same data set twice with different gradients to get interesting results.

Gradient: black red left-right above
Data: data1.txt

Gradient: black red bottom-up
Data: data1.txt

chart-two-gradient2.plt

Grid-Position: top
Grid-Color: black

Gradient: #000030 blue left-right above
Data: data1.txt

Gradient: black red top-down below
Data: data1.txt

chart-two-gradient3.plt

When using filled/gradient plots, it's often useful to put the grid on top of the charts.

Grid-Position: top
Grid-Color: #803030

Gradient: green blue top-down above
Data: data1.txt

Gradient: yellow red top-down below
Data: data1.txt

chart-two-gradient4.plt

Craazy.

Grid-Position: top
Grid-Color: black
Grid-Opacity: 0.2

Gradient: #000030 blue left-right above
Data: data1.txt

Gradient: black red top-down below
Data: data1.txt

chart-two-gradient5.plt

But when putting the grid on top like this, it's usually more visually pleasant to make the grid non-opaque.

Gradient: black 25-purple-50-white-75-purple-black
Data: data1.txt

chart-gradient-more-stops.plt

You can also have more stops. In that case, the second element specifies the percentage points of where each color ends, so the above starts with black, then at 25% it's purple, then at 50% it's white, then it's back to purple again at 75%, before ending up at black at a 100% (but you don't have to include the 100% here -- it's understood).

X-Label: Day
Y-Label: Money
Margin-Left: 40
Margin-Bottom: 40
Grid-Position: top

Data: data1.txt

chart-labels.plt

You can put labels on the axes. If you're using the compact layout (as we are in these examples), you have to open up some space for the labels manually -- in the normal layout, there's already space for labels.

Data-Format: date
Smoothing: moving-average
20090101 157
20090102 156
20090103 152
20090104 152
...

date-chart2.plt

You can also use the date format to plot date series. And another feature demonstrated here is that you can have eplot smooth the data before plotting.

Data-Format: time
144000 78.0
145003 170.1
150014 212.9
...

time-chart-long.plt

Similarly, you can also do intra-day time plots -- this takes a HHMMSS format.

Data-Format: xy
Data: data-circle.txt

chart-xy-circle.plt

eplot isn't really geared towards doing 2D plots -- it's for time series and bar charts. But it can do rudimentary 2D plots, but it lacks some of the control you'd expect.

Background-Image-File: background.jpg
Grid-Color: #333
Color: white
Data-File: data1.txt

chart-background1.plt

You can put lovely wood grain images in the background to simulate being back in the 70s.

Background-Color: #888
Background-Image-File: background2.jpg
Background-Image-Cover: plot
Background-Image-Opacity: 0.6
Grid-Color: #333
Color: white
Data-File: data1.txt

chart-background2.plt

And you can put the background image over the entire chart, just behind the plot, or just in the frame. And also adjust the opacity.

Chart-Color: white
Grid-Color: #444
Background-Gradient: blue black right-left
Data-File: data1.txt
Gradient: red black

chart-gradient-background.plt

You can also have a gradient over the entire background, of course.

Header-File: external-headers.plt

If you're plotting a lot of charts, you usually want to have the same basic parameters. So you can put those in one file, and then include them like this. You can also use the `M-x eplot-with-headers' command, which will plot using the data in the current buffer, but taking the headers from that file.

So there's a lot of different headers you can use to influence the look of the chart and the individual plots. To get a list of them all, and their possible values, use the `M-x eplot-list-chart-headers' command.

You can have comments in a .plt buffer -- all lines that start with a # are comments.

eplot-mode

The major mode for editing .plt files is very simple. It does some font-locking and then provides the following commands:

C-c C-c: Display a buffer with the rendered image. C-c C-e: List all the different headers and document them. TAB: Autocomplete headers.

eplot-view-mode

The buffer used to display the charts uses another simple major mode with some convenient commands.

C-c C-s: Save the image to a file. C-c C-w: Specify an image width and then save the file.

If saving to a different format than SVG, the "convert" or "rsvg-convert" external programs are needed to do the conversion.

The C-c C-w command needs "rsvg-convert", because it renders the SVG chart at a specific size. This avoids scaling artefacts (blurring, etc), and you get a crisp, nice chart at any size you require.

Installation

If you're installing this manually (I guess it'll be on an ELPA after it's finished), put something like the following in your Emacs init file:

(push "~/src/eplot/" load-path) (autoload 'eplot "eplot" nil t) (autoload 'eplot-mode "eplot" nil t) (unless (assoc "\.plt" auto-mode-alist) (setq auto-mode-alist (cons '("\.plt" . eplot-mode) auto-mode-alist)))

Adjust the path you're pushing to load-path depending on where you put eplot.el.

API

(Probably more to come here...)

All the headers can have defaults set programmatically so that you can define an overall look that you prefer (and then override with explicit headers when you want).

This is done with the eplot-set function:

(eplot-set 'width 600) 
(eplot-set 'height 300)
(eplot-set 'font "arial")
(eplot-set 'background-color "#ffe0e0")
(eplot-set 'grid-color "#c0c0c0")

chart-simple.plt

You can put this in your Emacs init file or somewhere, but then you also need a

(require 'eplot)

first.