Skip to content
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

GradientLineCollection class has been added to support multicolored lines #19286

Closed
wants to merge 1 commit into from

Conversation

ufukty
Copy link

@ufukty ufukty commented Jan 13, 2021

PR Summary

example usage of addition

First 2 lines regular LineCollection lines. Sequential lines produced with GradientLineCollection. Code for this example is below.

Motive

Showing directional edges with arrows makes the image so cluttered, if the network has too much edges and nodes. So, the better way to differentiate which end is which end is drawing them with different colors. I recently shared a work at Reddit's r/dataisbeautiful community and people's reaction showed that this sort of visualization has some value in the eyes of audience.

Implementation

My implementation is not the perfect alternative. In summery, GradientLineCollection class is regular LineCollection class, although it creates that gradient effect by splitting each line into pieces smaller individually colored lines. Since, I already overly exceeded my free time, I can't dive in the deeper areas of API. I think that implementation will work great until someone figure out better way.

Example of possibility with addition

That image shows the subreddits with most hyperlinks. Orange for outgoing links, blue for incoming links. Image shows that incoming links are well distributed to larger set of communities compared to outgoing links.

network visualization example

Example usage

# Regular version
lc = mpl.collections.LineCollection(
    [[(0, 4), (1, 4)], [(0, 4.3), (1, 4.3)]],
    colors=["r", "b"],
    linewidths=10,
    alpha=0.8,
)

glc1 = GradientLineCollection(
    [[(0, 3), (1, 3)]],
    gradient={
        0.0: "red",
        1.0: "blue",
    },
    linewidths=10,
    alpha=0.8,
    pieces=50
)

glc2 = GradientLineCollection(
    [[(0, 2), (1, 2)]],
    gradient={
        0.0: (1, 0, 0, 1),
        0.4999: [1, 0, 0, 0],
        0.5: "#0000ff00",
        1.0: [0, 0, 1, 1],
    },
    linewidths=10,
    alpha=0.8,
    pieces=200
)

glc3 = GradientLineCollection(
    [[(0, 1), (1, 1)]],
    gradient={
        0.0: "red",
        0.2: "yellow",
        0.4: "green",
        0.6: "cyan",
        0.8: "blue",
        1.0: "magenta",
    },
    linewidths=10,
    pieces=200
)

ax = plt.gca()
ax.add_collection(lc)
ax.add_collection(glc1)
ax.add_collection(glc2)
ax.add_collection(glc3)

PR Checklist

  • Has pytest style unit tests (and pytest passes).
  • Is Flake 8 compliant (run flake8 on changed files to check).
  • New features are documented, with examples if plot related.
  • Documentation is sphinx and numpydoc compliant (the docs should build without error).
  • Conforms to Matplotlib style conventions (install flake8-docstrings and run flake8 --docstring-convention=all).
  • New features have an entry in doc/users/next_whats_new/ (follow instructions in README.rst there).
  • API changes documented in doc/api/next_api_changes/ (follow instructions in README.rst there).

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for opening your first PR into Matplotlib!

If you have not heard from us in a while, please feel free to ping @matplotlib/developers or anyone who has commented on the PR. Most of our reviewers are volunteers and sometimes things fall through the cracks.

You can also join us on gitter for real-time discussion.

For details on testing, writing docs, and our review process, please see the developer guide

We strive to be a welcoming and open project. Please follow our Code of Conduct.

@ufukty
Copy link
Author

ufukty commented Jan 13, 2021

related #6040

@jklymak
Copy link
Member

jklymak commented Jan 13, 2021

This seems interesting, and I assume the line can be curved.

However, we already have an API for mapping between colors and numbers between 0 and 1. I think it would be better if your "gradient" argument were replaced by a colormap/norm pair for consistency with the rest of the library. I also think that would save you a lot of new code.

@ufukty
Copy link
Author

ufukty commented Jan 14, 2021

@jklymak I don’t think lines can be curved. I thought there are only predefined cmaps. If they allow customization the way current solution does then gradients could be replaced

@jklymak
Copy link
Member

jklymak commented Jan 14, 2021

Sure there is a whole tutorial on how to create colormaps. https://matplotlib.org/tutorials/colors/colormap-manipulation.html

@ufukty
Copy link
Author

ufukty commented Jan 15, 2021

Thanks for link. Will look into it when I get a chance

@jklymak jklymak marked this pull request as draft May 10, 2021 16:28
@melissawm
Copy link
Contributor

Hi @ufukty - are you interested in continuing this work? If so, please mark the PR as ready for review and let us know if you need help with the rebase, we have instructions for that here. Thanks!

@github-actions
Copy link

Since this Pull Request has not been updated in 60 days, it has been marked "inactive." This does not mean that it will be closed, though it may be moved to a "Draft" state. This helps maintainers prioritize their reviewing efforts. You can pick the PR back up anytime - please ping us if you need a review or guidance to move the PR forward! If you do not plan on continuing the work, please let us know so that we can either find someone to take the PR over, or close it.

@github-actions github-actions bot added the status: inactive Marked by the “Stale” Github Action label Sep 27, 2023
@timhoffm
Copy link
Member

As given, this is a nice application and is thus not well suited for core matplotlib. If somebody has interest in following up, I suggest to start a third-party package. If we go towards for lines inside core matplotlib, #28242 is the more general approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging this pull request may close these issues.

None yet

4 participants