Skip to content

Phasor plot#4096

Merged
swharden merged 14 commits intoScottPlot:mainfrom
CoderPM2011:feat/Phasor
Jul 25, 2024
Merged

Phasor plot#4096
swharden merged 14 commits intoScottPlot:mainfrom
CoderPM2011:feat/Phasor

Conversation

@CoderPM2011
Copy link
Contributor

I added PhasorLinesPlot and used it with PolarAxis(#4055) to implement the plot in #3939.

PhasorLinesPlot modified from LinePlot.

  • Only End needs to be set, since Start is already specified as Origin, according to which the class has been adjusted.
  • The PaddingFraction and PaddingArc properties were introduced because of the need to adjust the position of the line name labels.
    • PaddingFraction is a scaling factor.
      It uses the smaller range length between the X and Y axes, multiplies it by the scaling factor, and then adds it to the label position.
    • PaddingArc is a coefficient designed for polar coordinate systems that represents the arc length from the label to the point.
      Since the radius is proportional to the arc length at the same angle, angles are not used to avoid differences in label positions with different radii.
  • Modify Render()
    • Render all lines.
    • "Marker" of "Origin" is not rendered.
    • Rotate the Marker according to the polar coordinates.
    • Render line name labels

Other changes

  1. To realize the arrow line, I added the rotation feature to Marker.
  2. To facilitate the calculation of the angle, the operator+ and operator- are added to it.

If this is not appropriate, please feel free to change it. 😀

resolve #3939

Result Image

image

Use code

var pol = myPlot.Add.PolarAxis();
pol.MaximumRadius = 30;
pol.RegenerateCircles(count: 3);
pol.RegenerateSpokes(count: 12);
foreach (var spoke in pol.Spokes)
{
    spoke.LinePattern = LinePattern.Dotted;
    if (spoke.Angle.Degrees % 90 != 0)
    {
        spoke.LabelStyle.IsVisible = false;
    }
}
foreach (var circle in pol.Circles)
{
    circle.LinePattern = LinePattern.Dotted;
}

var pts1 = new PolarCoordinates[]
{
    new (30, Angle.FromDegrees(0)),
    new (30, Angle.FromDegrees(120)),
    new (30, Angle.FromDegrees(240)),
};
var names1 = new string[] { "V L1-N", "V L3-N", "V L2-N" };

var pts2 = new PolarCoordinates[]
{
    new (10, Angle.FromDegrees(30)),
    new (10, Angle.FromDegrees(150)),
    new (10, Angle.FromDegrees(270)),
};
var names2 = new string[] { "I L1", "I L3", "I L2" };

var phasor1 = myPlot.Add.PhasorLines(pts1, names1);
var phasor2 = myPlot.Add.PhasorLines(pts2, names2);

phasor1.LegendText = "phasor 1";
phasor2.LegendText = "phasor 2";

@swharden
Copy link
Member

Hi @CoderPM2011, thanks so much for this PR! I may rework it a bit, but I intend to merge tonight.

I recognize you put a lot of work into adding rotation to many of the path-based markers and added an inheritance system. To keep things simple I'll probably roll back the inheritance system and maybe add a static method somewhere that lets users rotate paths.

However, I'm thinking the phasor system may benefit from using ArrowStyle instead of a LineStyle and Marker. In addition to supporting rotation out of the box, arrows are designed so the tip points to a coordinate. Presently the rotation-based marker systems causes the arrowheads to "overshoot" their target as seen in the screenshot below.

image

I may peter out before merging tonight, we'll see how far I get! I'll follow-up with a message here either way 👍

@swharden
Copy link
Member

Actually, I'm hesitant to say this because I know this PR represents a lot of work and time 😅 .... but we may not actually need a phasor plot if we can add Arrow directly on top of the new polar axis. There may be some functionality here I'm not considering though. I'll give this a quick try in the cookbook so we can compare and contrast the two strategies, then decide how to best proceed from there 👍

@swharden
Copy link
Member

This strategy is looking promising! Maybe there's still a use case for having a PhaserPlot to hold a collection of similarly-styled arrows, and they can use this arrow logic instead of marker logic. I can tell this is getting a bit more work than I initially thought so I'll probably have to put this down for today, but I'll merge in some of the progress I made and you're welcome to run with it if you have additional ideas!

// these are the points we will display
PolarCoordinates[] points = [
    new (10, Angle.FromDegrees(15)),
    new (20, Angle.FromDegrees(120)),
    new (30, Angle.FromDegrees(240)),
];

// start by adding a polar axis to the plot
var polarAxis = myPlot.Add.PolarAxis(30);
polarAxis.LinePattern = LinePattern.Dotted;

// then place arrows representing each polar point
IPalette palette = new ScottPlot.Palettes.Category10();
Coordinates center = polarAxis.GetCoordinates(0, 0);
for (int i = 0; i < points.Length; i++)
{
    Coordinates tip = polarAxis.GetCoordinates(points[i]);
    var arrow = myPlot.Add.Arrow(center, tip);
    arrow.ArrowLineWidth = 0;
    arrow.ArrowFillColor = palette.GetColor(i).WithAlpha(.7);
}

image

@CoderPM2011
Copy link
Contributor Author

@swharden thanks for your reply.

I hadn't noticed the existing Arrow plot.😅
After changing PhasorLinesPlot to like Arrow, it works great.😊
image

Regarding the Marker part, I'm not sure how to adjust it, so I'll just leave it as it is.

@swharden
Copy link
Member

This is looking great and I'm about to merge it in! An idea for a future feature could be adding support (or a new plot type?) for curves to allow users to create figures like this:

image

@swharden swharden changed the title Added phasor plot Phasor plot Jul 25, 2024
@swharden swharden merged commit 5989f8a into ScottPlot:main Jul 25, 2024
@CoderPM2011 CoderPM2011 deleted the feat/Phasor branch July 25, 2024 23:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Phasor diagram in a polar coordinate plot

2 participants