-
Notifications
You must be signed in to change notification settings - Fork 782
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bubble Plot #984
Bubble Plot #984
Conversation
…gon. Also added Hatch support and fixed the axis limits to include the radius of the circle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, most of my review is trivial things like changing comments.
The one concern I do have is whether we ought to have a plottable for creating a single circle, or should we have a plottable which plots an array of circles. The user could then plot a single circle by passing in an array with one item (perhaps helped by another method in Plot.Add
).
I think the latter is preferred, because if a future CirclePlot
or BubblePlot
is to be added, it seems unfortunate to require they have to create lots of Circle
objects which duplicates lots of fields. For example, a BubblePlot
would likely have its own fields for tracking fonts, line widths and colours, which axis it's associated with, etc, etc. Having one class that draws lots of circles minimizes that duplication.
The approach described above is how AddScatter
and AddPoint
work, both create a scatter plot, but AddPoint
creates a scatter plot with only one point in it. Let me know what you think.
Hi @PeterDavidson, It looks like you work is based on On the other hand, if we look closely, then the circle has nothing in common with the text, the text does not adjust to the circles, and the circles do not adjust to the text in any way. What I like the most is the idea of creating |
Displaying Multiple Shapes
I agree with @bclehmann's suggestion - it would be nice for one plottable to be able to display many circles. Inheritance and Plottables
If I had a deep understanding of the problem domain (exactly what functionality people would find useful) it would make sense to design and implement a complex inheritance tree (e.g., an abstract base class that text and shape inherit from, interfaces for shapes like circle and square, etc.) for these shape-plotting modules. However, I think I am still exploring the problem domain here, and am inclined to avoid inheritance for experimental features like this until I understand it better. I'm often surprised by how people use this library - it's not always what I would have predicted - so instead of trying to architect the perfect solution up-front my strategy is to keep experimental modules (like bubble plots) segregated from the rest of the modules base by minimizing inheritance. That's a long answer, but it's the reasoning behind why I tend to prefer duplicating code over inheritance for plottables. Immediate Next StepsI'll refine this PR today, merge it in, and release a new package shortly. I think this plot type will/should continue to evolve, but it will be nice to have have some of this functionality available immediately. Thanks again @PeterDavidson for getting the ball rolling here! Long-Term Goal: Expand Marker FunctionalityI'm not going to step in this direction right now... but some day I think markers should be smarter (size, fill, border, etc. and also |
I'm converging onto something like this... I'm thinking we should keep text/font/labels/alignment out of this plot type. There's already a plot type to add text to plots, and it's easy to add to the plot at any time. Simple Exampledouble[] xs = ScottPlot.DataGen.Consecutive(31);
double[] sin = ScottPlot.DataGen.Sin(31);
double[] cos = ScottPlot.DataGen.Cos(31);
var plt = new ScottPlot.Plot(600, 400);
plt.AddBubblePlot(xs, sin);
plt.AddBubblePlot(xs, cos);
plt.Title("Simple Bubble Plot");
plt.SaveFig("simple.png"); Advanced Exampledouble[] xs = ScottPlot.DataGen.Consecutive(31);
double[] ys = ScottPlot.DataGen.Sin(31);
var cmap = ScottPlot.Drawing.Colormap.Viridis;
var plt = new ScottPlot.Plot(600, 400);
var myBubblePlot = plt.AddBubblePlot();
for (int i = 0; i < xs.Length; i++)
{
double fraction = (double)i / xs.Length;
myBubblePlot.Add(
x: xs[i],
y: ys[i],
radius: 10 + i,
fillColor: cmap.GetColor(fraction, alpha: .8),
edgeColor: System.Drawing.Color.Black,
edgeWidth: 2
);
}
var plt = new ScottPlot.Plot(600, 400);
plt.Add(myBubblePlot);
plt.Title("Bubble Plot");
plt.AxisAuto(.2, .25);
plt.SaveFig("advanced.png"); |
Okay this landed in a good spot. A quick summary of where we are:
|
Purpose:
#960 talks about a new plot type, BubblePlot, and a simpler IPlottable Circle to just draw a single circle with the radius expressed in chart units. #973 also asks for the ability to produce a single circle. This PR implement the single circle plottable. I have named it Circle (rather than CirclePlot, which was suggested in #973) since that seems to better match the naming convention used for Polygon.
If you are happy with the overall approach then I can add a new AddCircle function to Plot and update the documentation/examples.
New Functionality:
A new plottable which allows a custom circle/ellipse to be drawn, with an optional label drawn at an offset from the center as specified in the Font.Alignment. The circle has the following data
It also has some fairly standard customization options - LineWidth, LineColor, FillColor, HatchStyle, HatchColor, Font, FontColor, FontName, FontSize, FontBold, Rotation.
Example of use
This is an example that effectively creates a bubble plot by creating a circle for each point in a list. Most of the customizations are applied here.