Comparison of plotting packages

Man, that goes straight to my hart. That rooster is from Azeite Gallo and it’s a custom symbol. It’s the logo of a very old Portuguese olive oil brand. Even the Brazilians here know it for sure.


How so? Can you elaborate

Sorry, elaborate what?

Ah, but the rooster is great! It is the neon green and red dots underneath it that make it look dated. To elaborate: old plotting software used to employ f00, 0f0, and 00f as standard line colors (in hex notation for RGB). Sure, these are the “base” colors, but perceptually they are a terrible choice for visualizing data.

1 Like

Ah, the bottom row. That’s entirely my fault. That picture is from a a GMT workshop where the intention was to show symbol fill as well as symbol outline pens control. And because I love green and needed a light color to not obfuscate the outline, it came out like this. Never thought it would be scrutinized in regard of perceptually visibility.

When I migrated to Julia, there was one particular point that I really enjoyed: I could choose one from many different plotting packages. The value of having the possibility to choose from various alternatives is only well understood when someone is deprived of that possibility for some reason. So, I would like to thank all those Julia people who have spent time and effort developing the packages we are using for free. And all of them!

That is why I think it looks nonsensical to propose (as someone did in the past in this forum) that the Julia installation should come up with ONE plotting package by default. That is also why I think when people show such strong feelings when somebody else’s choices (tastes) are displayed, it looks awkward and strange. Those are my choices and preferences, and I do not have the slightest intention to indoctrinate anybody.

Regarding the comment by @Krastanov, I am not a great expert in LaTeX, but I know a little about it. Therefore, the best I can come up with is the following:

  1. No, linking only to the gallery of examples of PGFPlotsX is not fair to the package. It can accomplish much more than is visible there. For instance, if one is curious about what can be achieved with this package, take a look at the book by Mykel Konchenderfer et al. (2022) here, it is free. The plots in this book were done with PGFPlots. If one finds the figures in the book ugly, they may have a very strong personal taste in plotting or are as talented as Picasso.

  2. Colors in LaTeX: I never heard complaints about problems using colors in LaTeX. So, with proper adaptation, we can use any colors we want inside PGFPlotsX.

  3. “inconsistent line thicknesses”: I have never heard of any complaints about such a problem, as far as the pgfplots manual is concerned here

  4. “ugly markers”: I find them quite beautiful! In fact, they do not seem (to me) very different from the markers we may find in any significant plotting package in Julia or Python. See, e.g., page 185 of the pgfplots manual above linked.

  5. “ugly serif fonts”: I think the original package uses standard LaTeX fonts. So, I do not understand what can be wrong with the serif fonts of LaTeX.

I am not a developer, so I am not qualified to discuss the technical issue raised by @joa-quim about the “plotting quality” between GMT and PGFPlotsX. I must confess, I have just gone into GMT and enjoyed what the package accomplishes. It is a pleasant surprise, and I have already learned something helpful from this thread. But as a user, and I do not work with maps, I still find the output produced by PGFPlotsX slightly better than that of GMT (but it may be due to my eyes, not my knowledge, dictating this).

Below I insert three plots (the first two produced with PGFPlotsX and the third with GMT). My eyes can easily choose.

A disclaimer: nowadays, I do all my teaching with PlotlyJS.jl and PlutoPlotly.jl. And I would like to thank everyone involved in the PGFPlotsX.jl, which is terrific and freely available to me, and everyone else if needed.


Fully agree that our eyes (and the back) make all the difference. One thing that I dislike both in GMT and PGFPlotsX is the use of the mathematical minus symbol in labels. They are just too large. Tried to change that in GMT (the C package) but lost the arguing.

Another thing is that you comparison with GMT is not right. The figure you showed is from a 3D bar plot, not a 3D surface view.

I’m going to be as bold as to offer some criticism of the plots in that book. It is a very nitpicky criticism, so it’s mainly to highlight how awesome pgfplots is: If you look at some of the plots in the large (Tufte-style) margins, you can see that when there are two or more plots, the axes do not always line up exactly (see e.g. page 21). This is because they have very differently sized labels and tickmarks.

But pgfplots has an option, trim axis, that allows sizing and positioning of axes to completely ignore the labels and tickmarks, so that one can easily align multiple independent plots with respect to the axes lines only. It actually allows labels to protrude out beyond the text limits and into the margins — which perhaps doesn’t sound great, but looks very slick.


Sorry, but I just used the code on the website. Did not try to bias the comparison. If I have more time, I will learn how to do the 3D surface view.

If you find the time, could you expand a bit about your plotting workflow and your solution to the 2-language problem for plots? Maybe with just an example of how you solve some plotting problem?

Eg recently I read about a plot type called a percentogram, and wanted to try it. In about 20 minutes I implemented

using PGFPlotsX, ArgCheck, StatsBase

function quantileogram(x; n = 11, p = range(0, 1, length = n))
    mi, ma = extrema(p)
    @argcheck 0 ≤ mi && ma ≤ 1 && n ≥ 5
    q = quantile(x, p)
    y = [(p[i + 1] - p[i]) / (q[i + 1] - q[i]) for i in axes(q, 1)[begin:(end - 1)]]
    z = zero(eltype(y))
    pushfirst!(y, z)
    push!(y, z)
    pushfirst!(q, q[begin])
    Table(q, y)

@pgf Plot({ const_plot }, quantileogram(randn(500)))

which yields something like

I usually write functions that transform data to a Table, then some functions which wrap those in Plots, then some which fill in Axis, then I modify the options with merge!(axis, @pgf { ... }).

PGFPlotsX allows me to implement any kind if plot I want straight from Julia, composing tiny functions.

The only downside is that the backend does not handle plots with a lot of elements — eg 10000 lines with opacity 0.2 that form some kind of pattern. I try to transform data first, eg binned scatterplots or loess, then it is fine. Plots with <1000 elements are fine.


Thanks for the illuminating example!

The limitation to a modest number of elements is the tradeoff of plotting with pgf and tikz; you get the highest quality, but they’re not designed for handling big datasets.

One thing I dislike in the PGFPlotsX is the disproportionate size of the labels. But I don’t get your argument. By slightly modifying your quantileogram function to return directly q,y, I can also do directly

using GMT
lines(q, y, steps=:x, close=:bot, show=1)

1 Like

I am not claiming that other plotting packages can’t do something similar; I just wanted to provide an example of how I use PGFPlotsX to answer @LeePhillips.

That said, wanted to use Makie in a similar way and I was disappointed to learn that this is currently not supported.

I think that there is a spectrum of approaches to plotting, from highly organized (like AlgebraOfGraphics.jl) to treating the plot area as special kind of canvas on which you draw stuff. I prefer the latter, but I fully realize that this is a personal preference.

That said, the major selling point of PGFPlotsX remains the native LaTeX integration, from both ways (LaTeX in your plot, and your plot in a LaTeX document).

I think that big datasets should not be plotted directly. Preprocessing is essential. Overplotting should always be avoided.


I tend to agree. But I’ve been spoiled by years of using gnuplot, which doesn’t complain about plotting millions of points.

That’s what @cormullion does so brilliantly with his Luxor examples (and GMT in its guts works on the same principles).


Maybe people use these plots in other ways than I do, but for my use case this remark doesn’t really make sense. The label size is something you set in the preamble of your LaTeX document. The plot you see here is just a ‘preview’ that shows the basic look, not the finished article. Both the font, the font size, line thickness or even plot mark settings can be completely different when you typeset the final document.


Also, as someone who has suffered through uncounted talks where I couldn’t read the axis labels because I wasn’t sitting in the front row, I say, make them big.


Aren’t both possible regardless of plotting package?

  • using LaTeXStrings; ylabel = L"\sigma_{eq}"
  • \begin{figure}; \includegraphics{MyPlot.png}; \end{figure}

I’ve never used PGFPlotsX, so I’m genuinely asking what the tighter integration is/enables beyond the conventional methods above?

So this includes a rasterized png image into the document. It is a ‘finished’ image, and does not include any information from the LaTeX document (except that the document sets its size.)

A pgfplots figure is neither a rasterized image, nor a vector image, it is LaTeX code, and will be compiled by your tex distribution. Anything can happen then, it can inherit fonts and font size settings from the parent document. You can change line styles and thicknesses, insert dynamically created labels and plot annotations, change colors, move things around (even change the input data, since pgfplots can read data from file), etc. etc. I don’t right now have time to think of all the different things that are possible with this approach (I’ve gotta run, sorry about the rambling), but you can imagine for yourself the possibilities when your image is latex code, not a static image.