When I run plot '<(echo 0 0)' u 1:2 w circles
with the SVG terminal, I get the attached output. What concerns me is that the circle is rendered using a <path>
element, rather than a <circle>
. It seems to me that this can lead to a "circle" that doesn't really look like a circle, e.g. if the plot is zoomed in significantly. Is there any reason gnuplot doesn't use the circle element here?
Observed on gnuplot Version 5.2 patchlevel 8 on Ubuntu 20.04.
Empirically that turns out not to be the case.
The attached plot contains one blue circle drawn as a path (
set obj 1 circle at 0.5, 0.5 radius 0.241
) and one purple circle drawn as an svg circle (set label 2 "" at 0.6, 0.5
) with suitable adjustment to the pointsize and linewidths.For the svg viewers I have here there is no apparent difference in quality of the two representations. Do you find otherwise?
Last edit: Ethan Merritt 2020-11-24
I can see issues more easily with smaller circles. For example,
plot [-1:1] '<(echo 0 0)' u 1:2:(0.005) w circles fs solid
— I can see distortion viewing at 150% with Chrome or Firefox; it becomes even more obvious as I zoom in further.True, although it looks better if you remove the fill border. If you want [very] small circles is there a reason you wouldn't use
with points pointtype 6
? I don't mind adding this as a feature request, in which case it would be best to have a sample use-case to justify it.Some background: what I'm trying to do is create what are sometimes called "dot plots" in the field of molecular biology, like the attached image. Basically, the size and/or color of the box plotted at position (i, j) represents a probability of nucleotides i and j pairing, an energy associated with that pairing, or something similar. (The attached plot was created with software I wrote during grad school, ~15 years ago. I did a rather mediocre job then, and it hasn't gotten better with age!)
I had a hunch gnuplot could do a better job with this than I can, and I saw two possibilities. The first was to
plot with points
, using a filled square (or whatever) as the symbol. The problem there was that the size was in some arbitrary (to me) "terminal coordinates", rather than in axis coordinates.Then I discovered
plot
tingwith circles
, which seemed to be a better fit because I could specify the radius in axis coordinates. So in a nutshell, wanting a single plot where some dots have radii as large as 1 and others are so small they get distorted when rendered as<polygon>
s led to this bug report.(By the way, is there any reason not to draw circles as
<circle>
s, aside from the fact that the<polygon>
approach is already implemented? It seems like being smaller and easier to read or parse might merit the change if there's no downside.)Going even further: I've thought of at least two reasons why
points
is preferable tocircles
. One is the ability to choose squares or other shapes in addition to circles; the other is that it's usable withlabels
andhypertext
, which is certainly relevant with the SVG terminal. Does it makes sense to convert this to a feature request that the size of a point be specifiable in axis coordinates, effectively mergingpoints
andcircles
into one feature? I know that would blow up the scope of this, but eliminating the tradeoffs betweenpoints
andcircles
(which seem arbitrary to me) would be the "gold standard" in my opinion.Some thoughts in random order:
The internal gnuplot API does allow for individual terminals to provide a custom circle-drawing routine. It was originally assumed that svg/cairo/qt/... might provide optimized rendering that would be better than a generic routine using arcs + fill. But that turned out not to be the case. The generic code does just as well in almost all cases. Plus it supports wedges, incomplete arcs, and other circle derivatives that e.g. SVG does not provide. So yeah, the hooks exist to add an SVG-specific routine but it would not cover the general case so it would have to inspect the request and bail to the generic code except in the simple case of a complete circle.
I don't see why your dot plot requires that the size of the dots is expressed in x-axis units. At worst you would need or want a scale factor for pointsize/axis-units, which could be further tweaked using the multiplicative scaling from
set pointsize
. You could even attach it to a pair of hot-keys for interactive visualization:... which brings up another possibility for your dot plots. Instead of using either numerical point type (7 = filled circle) or a polygon (circle) you could use unicode character glyphs. See for example https://jrgraphix.net/r/Unicode/25A0-25FF . In gnuplot the are several ways you could do this but the simplest is to specify the point type as a UTF8 character. Again this can be done in several ways:
You can vary the sizes of individual points by changing either the font size or the point size (this depends on exactly what command you end up using).
http://gnuplot.sourceforge.net/demo_svg_5.5/hypertext.html
I tested with (and without)
noborder
and found the results to be different but not necessarily better either way. In fact, withnoborder
, some distortion was evident to me even without zooming. However…the argument about arcs and wedges is a good one. I'm not the one who has to maintain the gnuplot codebase :) and even I now have second thoughts about special-casing a full circle for terminals that support it.I don't know if I can really say why the definition of a dot plot is what it is. I guess as a developer I'm used to asking what and how, but not why. Doesn't the fact that
with circles
exists indicate that there's value in being able to size the circles based on plot coordinates? I think bothwith points
andwith circles
have applications; I'm just kinda bummed that I can't get the features of both at once (i.e. hypertext, maybe squares instead of circles, but sizeable).A while ago I tried to figure out a scale factor that would make
with points pointtype 5
(or 7) do what I was after. The issue was that while I could get one that was close enough for a particular plot, it was specific to the size of the axes, the size of the overall plot and which terminal it was. I could certainly tweak, say, a single plot for a publication until it was perfect, but that process doesn't scale well to lots of plots, much less is it automatable. (Again, I'm guessing this is whywith circles
was created?)That's kind of backwards. The motivation for
circles
was to create individual objects that (1) would remain a circle independent of the x/y axis ratio, and (2) you could optionally specify the radius in terms of fractional graph or fractional screen coordinates so that the circles did not scale on zooming. Later it was extended for use as a plot stylewith circles
in addition to definition of individual circular objects. In the context of plotting, the intent was to make it act likepointtype 6
except that you could draw arcs, wedges, etc.I'm still not seeing the difficulty in creating figures for publication using character-based point types. I do this myself for $dayjob$. Usually you are constrained to use a specific font size for the figure text anyhow, so specifying the size of the points in terms of font size makes it scale with the rest of the figure. In fact I would find it very annoying if changing the x axis range or scale caused all my points to change size. So I guess I just have a different mental model for laying out the figure.
Here is an example that looks vaguely like your AsuTRI plot. It uses yet another gnuplot command variant
with labels
. Each dot is a randomly generated fraction of the base font size. The color varies with the y coordinate. For a smallish number of dots, this is probably how I would do it.I get the sense we aren't quite understanding each other here. Part of the problem I'm trying to solve is drawing boxes or circles whose size, in axis units, is part of the data to be plotted. Put another way, the requirement is that when two adjacent dots have size 1, they neither overlap nor have space in between.
I gather this isn't of much interest to anyone else, but it's what I'm doing. I can't just choose to solve a different problem because it's easier than the one I'm working on. :)
Anyway, I don't know how much it matters, because it just dawned on me that my OS is already one minor version behind on gnuplot, which means even if my pet feature were added, I couldn't count on it to be widely available right away. ("Widely available" is ill-defined here because I don't know exactly what form this project might ultimately take. I could always compile my own gnuplot for, say, a single web server, but that approach doesn't work for software users install on their own machines. I'm far from committing to either architecture at this point.) So I'm inclined to say we don't worry about this anymore. Thanks for listening!
If drawing with boxes is allowed, I would suggest using
boxxyerror
instead of circles style. This style allows the size of the box to be determined by the units of each axis, and the fill color can also be determined from the data. Seehelp boxxyerror
for detail.Could you try the following sample script?
The input data file 'test.dat' is like this.
The result svg file is attached.
That's perfect! How did I not discover that on my own?
boxxyerror
is what I was looking for all along. (Actually it goes beyond the minimum I need, but I've learned to expect that from gnuplot!)Thanks for cluing me in, and thanks to you and Ethan for all of the discussion. I learned plenty even from the "dead ends", which means it was all time well spent (for me at least).
I hope this post doesn't distract from the main discussion since it's from a different perspective.
In the current implementation of svg terminals, the endpoints of a line have a positional accuracy of up to one decimal place. That is, for the default size of the SVG terminal (600x480), the line endpoints are snapped onto a 6000x4800 grid. Of course, the line between the endpoints will be drawn as vector. The current positional accuracy may not be practically sufficient for "Scalable Vector Format" (to the extent that some people can recognize it with 150% magnification in firefox).
Isn't it possible that this positional accuracy to, for example, a resolution of two decimal places (on a 60,000x48,000 grid) would satisfy many people in practical purposes (not recognizable at 150% magnification, maybe)? As a trade-off, though, we have to put up with a file size up to 1.25 times larger.
Last edit: Hiroki Motoyoshi 2020-11-27
On line 117 of svg.trm you will find:
If you change those two value to, say, 100. and 2 respectively and recompile it should act exactly as you ask.
Thank you.
When I tried it with the plot command,
it was indeed accurate enough for practical purposes for enlargement. (See attachments which are captures of svg output on 'chrome' screen)
However, when I tried the same plot on other vector format terminals (pdfcairo, pdf, postscript), I saw the same distortions that are the problem here. This means that the accuracy of line endpoints is somewhat limited even for vector terminals. I guess this is because the bitmap and vector terminals share a line drawing routine.
Last edit: Hiroki Motoyoshi 2020-11-27
The cairo-based terminals (pdf/pngcairo/cairolatex/wxt) have a similar scale factor GP_CAIRO_SCALE, defined in gp_cairo.h.
The canvas terminal uses CANVAS_OVERSAMPLE.
For postscript it is PS_SC, defined in post.h.
And so on.
The scale factor for the current terminal is exported to the user in GPVAL_TERM_SCALE
I do not recall any previous requests to increase the terminal sampling, but the code was written to make it easy to change at build time if required. I suppose there could be a configuration option to increase all of these terminal-specific scale factors when the program is built.
Such an option would be helpful in cases like this one!
I would enable it if it were introduced :-)
I recommend everyone subscribed to this ticket move to https://sourceforge.net/p/gnuplot/feature-requests/490/ instead, if they still want a real circle.