Open EFanZh opened 4 years ago
Hi EFanZh, actually Plotters support real number already (See this example https://github.com/38/plotters/blob/master/examples/chart.rs#L17).
However, for histogram series, it needs the coordinate to be discrete, so that we have well defined buckets. Currently we don't have a way to do that, but the next major release will be shipped with better solution than use integer coord for discrete coord requirement.
I am not sure if this answers your question, if not, could you please share more use case, so that we can have a more concrete scenario?
Thanks you so much
I mean the coordinates that is used to draw on backends (drawing::backend::BackendCoord
):
This image is generated using plotters. As you can see, all the coordinates in it are integers. I think real number coordinates could improve precision if the image is enlarged, especially for vector images.
I see what you mean, but this might be tricky.
Since plotters has the backend independent drawing API, which means all the backend - but apparently having half pixel isn't supported in most of other backends. This breaks the plotters promise - which is the drawing result should be mostly unrelated to the backend (Because most of the backend need to truncate the backend coord anyway).
I think one of the possible precision mitigation would be creating a higher resolution image, this will gives you better precision, as long as it's vector graph, it's not really a difference (you could always use viewBox attribute for that purpose). Unfortunately, current published version doesn't have a way to set the viewBox, but this should be shipped with the next minor release.
If this is the case, I would like to change this feature request to track the customized viewPort API. Also please let me know if you think there's anything can't addressed by the viewPort.
Thanks!
Generating a high-resolution image then scale it down can already be done by the web page displaying it. I think supporting view port has little use here. And it is hard to determine how much should I scale the image.
Also, I found that actually most backends supports half pixel coordinates:
So maybe f64
is a better choice for backend coordinates?
I think supporting view port has little use here
Actually you can use the combination of viewPort and height + width attribute to make the svg in correct original size, at the same time you can improve the plotting precision. Actually viewBox
seems to be a good solution on this: https://jsfiddle.net/c6v9n10g/ (This means you don't need to zoom it yourself)
But accepting f64
doesn't necessarily means it can really support it, for those pixel based devices, integer is the physical limit. In addition, I am worry about when f64
is used as the coordinate type, it would introduce a huge performance regression in the bitmap backend, which have been used in embedded device display already. Please note real-time rendering on low power device is one of the use case of Plotters and there are actual users.
So I still hold the idea that we would keep current definition as long as it's
Changing backend coordinate might also be a breaking change and seems doesn't give a huge benefit. For SVG case, I believe viewBox
is the solution to all the problems.
I see your point, and I still have a few arguments here:
Thank you for being patient with me. I totally understand if you donβt want to changing the current implementation. I am currently OK with integer coordinates and the quality of the output image. Plotters is very good as it is, I just think the quality of the generated image could be better.
I am glad to have this conversation, I understand your point but I believe for anti-aliasing we can use alpha channel instead which is already supported by the API. I personally would rather be conservative to all API changes. And I think backend defined coordinate type would be one of the reasonable option, I am really appreciated about this idea - But just let me put this on my backlog since I don't think I will prioritize this work for now. But again, thanks for your advice and if you don't mind I would like to change the title of issue and keep it open as a backlog item.
Thanks again!
Could this be done with generics? That way we could maintain full compatibility with existing code and integer-only speed for applications that need it.
I'm new to this plotter crate. I think this crate is wonderful. Really thanks to your efforts!
By the way, I really wish that it supports non-integral coordinates. It also causes not-really-good-quality plots. Here is a SVG-backend version of the parabola example illustrated in the quick start. As you can see, the curve is jaggy and not really beautiful.
Hi, I would like to call attention to another way in which this would be relevant for raster backends. I believe issue #283 might be caused by this.
When plotting a function, the usual process is to choose a sampling grid in the x axis, then evaluating the function at these x positions. Setting an appropriate sampling resolution is sometimes difficult, especially when the code doesn't yet know the final pixel resolution at which the plot will be rendered.
If we set the sampling resolution too low, we end up with visible corners in the plotted line because the piecewise linear approximation doesn't sufficiently approximate the underlying function.
However when setting the sampling resolution too high, we might end up with a situation where the sampling resolution is greater than the pixel resolution. The quantized line segments generated in this setting will often have a length of just one pixel and end up exactly horizontal or vertical. Depending on the path rendering method used, this can effectively disable anti-aliasing.
The effect is most visible in regions with small slopes, for example at the top of the arch here. Note that both of these images have been scaled up (without resampling) by a factor of 3 to make it easier to see.
I believe for anti-aliasing we can use alpha channel instead which is already supported by the API
I think if we want to solve this by using the alpha channel in the API, we effectively have to move the rasterization to happen inside plotters, so that the backend can receive different alpha values for pixels along the border of the plotted line. That's of course a possible option but I feel like it would kinda go against the purpose of having different rendering backends in the first place, because that way the backend effectively receives an image and is just responsible for displaying that somewhere. Or maybe I'm completely misunderstanding what you propose here, in this case please do elaborate!
As far as I can tell, calculations within plotters are currently generic in the coordinate type, so I also think that letting the backend specify a preferred coordinate type would be a good solution, because it would not break embedded applications that don't want to or can't deal with floating point calculations. You mention that this would be a breaking change, but it feels like this would only be breaking for backend providers and not for end-users, or am I wrong on this?
Either way thank you for your valuable work on this library, it's overall a very enjoyable experience!
It seems we should allow each backend define their own coordinate type. For example, the SVG standard actually allows float point numbers, but plotters currently uses
BackendCoord
for all the backends.=== Original Conversation Currently, it seems that plotters only supports integer coordinates, so for SVG backend, some detail could be loss in the graph due to integer coordinates. Could real number coordinates be supported so the lines and curves could have more precision?