Sequential Multiwinner Voting Methods Visualized

If you haven’t seen the previous ternary plot diagrams I have done for single winner voting methods and apportionment algorithms, you might want to check those out as well.

The fallowing ternary plot represents what portion each of 3 different groups of voters (the cyan group, the magenta group, and the yellow) makes up of the electorate:

The closer you are to one of the 3 corners the more the group of voters that corner represents make up of the electorate. If you are directly on one of the corners, then the entire electorate composes of just the group of voters that corner represents.

The three groups of voters represented in that ternary plot have the fallowing preferences:

Cyan Candidate Magenta Candidate Yellow Candidate
Cyan Group 10/10 0/10 3/10
Magenta Group 7/10 10/10 0/10
Yellow Group 0/10 5/10 10/10

Like in my single winner voting methods visualized post and apportionment algorithms visualized post, each of the fallowing diagrams represents what the winners would be under different electorates. In each election the rules are modified such that each candidate can win multiple seats as if they were replaced by a clone everytime they won a seat. The methods I have chosen to compare are the two most established party agnostic proportional voting methods (STV and both versions of RRV) along with the 3 multi-winner method proposals the Equal Vote 0-5 PR Reaserch Committee I am on has came up (you can read up on each of those here: as well as one additional method: Sequential proportional score voting (which is just SPAV + KPT). Though I plan to create diagrams for many more sequential and optimal PR methods in the future.

Re-weighted Range Voting (D’Hondt/Jefferson version, 2 winners):

Re-weighted Range Voting (Sainte Lague/Webster version, 2 winners):

STV (2 winners):

SSS (2 winners):

SMV (2 winners):

Re-weighted STAR (2 winners):

Sequential Proportional Score Voting (2 winners):

Re-weighted Range Voting (D’Hondt/Jefferson version, 3 winners):

Re-weighted Range Voting (Sainte Lague/Webster version, 3 winners):

STV (3 winners):

SSS (3 winners):

SMV (3 winners):

Re-weighted STAR (3 winners):

Sequential Proportional Score Voting (3 winners):

Re-weighted Range Voting (D’Hondt/Jefferson version, 4 winners):

Re-weighted Range Voting (Sainte Lague/Webster version, 4 winners):

STV (4 winners):

SSS (4 winners):

SMV (4 winners):

Re-weighted STAR (4 winners):

Sequential Proportional Score Voting (4 winners):

Re-weighted Range Voting (D’Hondt/Jefferson version, 5 winners):

Re-weighted Range Voting (Sainte Lague/Webster version, 5 winners):

STV (5 winners):

SSS (5 winners):

SMV (5 winners):

Re-weighted STAR (5 winners):

Sequential Proportional Score Voting (5 winners):


And finally, this is what I speculate (and apparently what Toby Pereira also speculates) what the ideal proportions of the legislature C M and Y should control are if the legislature had a number of seats that approached infinity. This is also what I believe harmonic voting with the probabilistic transformation instead of the KP transformation reduces to in that case when there are infinitely many seats to fill (though the KP transformation and probabilistic transformation are equivalent when there are just 3 parties):

Here’s it side by side with what would be the ideal from a pure party list PR perspective (ideal is on the left and the distribution of 1st preferences is on the right.):

Though you can take that last diagram with a grain of salt, as it’s just speculation. If you believe that the ideals of proportional representation should be strictly just to make the number of seats each party gets to be proportional to the 1st preferences of voters (like in a party list sense), then to you the ideal proportions would instead be equivalent to the 1st diagram (the one showing the different proportions of each of the 3 groups).

1 Like

They’re colorful!

I can’t say I fully understand what they are really communicating. But it would be awesome if they could be made into some kind of widget that allows you to drag sliders around to experiment with them.

I’ll admit I’m not a fan of things that make the assumption that there must be parties, and that most everyone belongs to one party or another, that completely reflects their point of view. As someone who also has a lot of experience with colors and color theory, that is just too black and white for my taste. :slight_smile:

That’s why I tend to prefer thinking of single winner systems (which tend to be the default in the US for most offices), where they elect a candidate that represents the entire electorate, rather than one neatly-defined subset thereof.

Each diagram takes 1-2 minutes to be generated in c++ on the computer I’m using. Don’t web applications take a lot longer to run then pure c++ code running directly on the PC? How much longer do they take on average? 10x? 100x? Is it something reasonable?

You could certainly compile them using WebAssembly, which can convert C++ into “sandboxed” machine code that runs pretty much as fast as regular C++ compiled code. But 1 to 2 minutes is a long time to wait.

I was also thinking, if they were fast, they could be run server side and generate SVGs. Maybe that’s extra work to make SVGs, but they would be way lighter weight to serve over the net. (this is for all of the ones that have what appear to be solid colors and straight-edged polygons) An SVG to represent one of those would be something like 1k each, maybe less if served as JSON and built into geometry client side.

You could also pregenerate SVGs and animate them client side. Probably a lot of work to do that, but if you did, it’d be super slick.

And who knows, there might be crazy things you can do with the alpha channel (pixel-by-pixel partial transparency) on images to simulate a lot more going on processing-wise. I’m kinda experienced with that. See (both the color picker itself, and the images, make creative use of alpha channel to make it animate super fast)

Yeah it’s kind of hard to explain. When I sent you this long reply on the github project thread did any of that help you?

Kinda? I mean, there is a lot of reading and video watching there, and some of it seems rather tangentially related to what you are doing.

One thing I’ve learned over many years (and admittedly had trouble accepting) is that people’s attention spans are limited. I could probably spend two hours trying to digest all that, but I don’t have those two hours now, and there isn’t anything in your initial presentation that really compels me to want to invest the time.

I think you should make a youtube video where you try to explain the gist of it in 3 minutes. I know you’ve put a lot of work into this, now you gotta sell it. (and not just to me)


Maybe when I get around to it. Though the gist is the closer you are to one of the 3 corners the more the group of voters that corner represents make up of the electorate. If you are directly on one of the corners, then the entire electorate composes of just the group of voters that corner represents.

Though if you read up on the ternary stuff you can figure out how to calculate the exact sizes of each of the 3 groups for any region on the plot.

1 Like

Ok. Is there a meaningful takeaway? Can I look at one diagram vs another and say “this method obviously works better”?

I explained in my previous posts some of the criterion violations you can see in the diagrams. Any time a point that lies on a line between two other points of the same color is a different color then those other two points, that’s a violation of the consistency criterion. Because none of these methods are optimal they all violate consistency however some violate it more then others since some of the methods are based off of optimal methods that pass consistency.

You can also see participation violations when when for any point when you draw a line from that point to a corner and then move that point closer to that corner while keeping it on the line the election result changes to one that is worse for the group of voters represented by the corner you are moving towards.

You can’t really see monotonicity violations right now but if I changed the groups of voters such that one of them had the exact same preferences as another with the exception of their score for just one party being higher/lower then the other group, then you might see some locations on STV where on lines parallel to the line between the two corners representing those two groups moving a point on that line closer to the other group hurts the party of which that group gave that party a higher score.

1 Like

Wait I just noticed an issue in re-weighted STAR. I forgot to make the last round STAR runoff a weighted runoff (all of the three groups have the same weight regardless of both the size of their group and their ballot weight). Fixing that now.

Edit: fixed

Edit: Nevermind. I thought I fixed it but there was still one last thing I forgot to do.

Edit: Fixed. Finally.


So, just curious, why do they take so long to run? 1-2 minutes in native code is some serious number crunching.

BTW hate to pick on spelling but I keep seeing it… it’s “following” not “fallowing”. :slight_smile:

1 Like

Because each time it runs it’s calculating the election results from about 454,144 different individual elections. Each pixel (except the ones in black) is a different election. I guess for a web application the number of pixels could be scaled down though.

Though I’ve never timed it. It’s probably less then 1 minute but when you are waiting for something to run it feels like forever so it feels like 1-2 minutes. It also might very a bit by system.

Could you post a plot showing deviation from ideal?

1 Like

Ok, makes sense. BTW, I’d suggest making the outside-the-triangle pixels white (or transparent if that is an option), especially if you’re going to post it somewhere it will appear on a white page. And they don’t need to be so big, I’d rather see a few on screen at once than see them in high resolution:


OK so I finally fixed Re-reighted STAR. Before it was just Re-reighted range just with the more powerful re-weight ( 1/(1 + 2*score_given) instead of 1/(1+ score_given) ).

The runoff does make it a little more chaotic. That’s probably because these groups of voters create a lot of Condorcet cycles and Condorcet cycles are things that runoff methods are not particularly good at handling (they tend to elect the candidate that beats the best candidate in a runoff and when they do that half the time (depending on the direction the runoff goes) that’s actually the worst candidate in the cycle). STAR had a simular problem in the plot I made for single winner methods here. So perhaps if I didn’t chose cycled preferences for this example Re-reighted STAR might not be as chaotic.

Is what you have in mind subtracting the colors of the ideal from the others? Because that can be done in photoshop (edit: I just realized you can’t because of the stuff I did to the colors to make it look a bit prettier, so it would still need to be ran in the code). Or do you mean showing the difference in average logarithmic quality of the approval ballots after the ballots have been converted into approval ballots through the probabilistic transformation (where each score has a treated as having a probability of becoming approve or disapprove based off of the score given, though done in a deterministic way)?

In either case, pick for a number of winners. I don’t want to do it for 2, 3, 4, and 5 winners because that’s 25 plots and each plot takes me 1 minute to create it (right now a lot of it is manual so I can’t just leave it alone. I can a lot of that but I can’t for the other stuff I have to do) but if you count the other stuff like converting the image format, moving files, redoing ones because you messed up, etc. it’s more like 2 minutes per plot which is a lot for 25 plots.

When I get around to it, I’ll do that. I’m just lazy and it’s easier to just lay them all out one at a time.

That sounds like the opposite of lazy. You’re doing so many things the hard way. I don’t want to tell you how you should code, but for all the time you’ve obviously put into this, you sure could can make life easier for yourself by building a few things to automate and speed up the process.

Also, to avoid having to convert image formats, you can just use LodePNG library and create PNG images directly: It’s super easy to drop into a C++ program. Here’s simple example code:

1 Like

1 Like

Much better to see them all together.