GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Add blend modes and blend groups for compositing by ayshih · Pull Request #31162 · matplotlib/matplotlib Conversation
|
| Blend modes | Agg | Cairo | SVG | PGF | PS | |
|---|---|---|---|---|---|---|
| normal | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| multiply, screen, overlay, darken, lighten, color dodge, color burn, hard light, soft light, difference, exclusion |
✅ | ✅ | ✅ | ✅ | ✅ | 🟡 |
| hue, saturation, color, luminosity | ✅ | ✅* | ✅ | ✅ | ✅ | 🟡 |
| knockout, erase, clear, atop, xor, plus | ✅ | ✅ | 🟡 | 🟡 | 🟡 | 🟡 |
| Blend groups | Agg | Cairo | SVG | PGF | PS | |
|---|---|---|---|---|---|---|
| neither isolated nor knockout (same as no group) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| isolated only | ✅ | ✅ | ✅ | ✅ | ✅ | 🟡 |
| isolated and knockout | ✅ | ✅ | 🟡 | ✅ | ✅ | 🟡 |
| knockout only | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ |
import matplotlib #matplotlib.use('TkCairo') import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Circle, Rectangle N = 10 data = np.arange(N**2).reshape((N, N)) % (N-1) fig, axs = plt.subplots(3, 8, figsize=(10, 5.5), layout="tight") axs = axs.flatten() fig.set_facecolor("none") blend_modes = ["normal", "multiply", "screen", "overlay", "darken", "lighten", "color dodge", "color burn", "hard light", "soft light", "difference", "exclusion", "hue", "saturation", "color", "luminosity", "knockout", "erase", "clear", "atop", "xor", "plus"] for ax in axs: ax.set_facecolor("none") ax.set_xlim(0, 1) ax.set_ylim(0, 1.2) ax.set_axis_off() for i, blend_mode in enumerate(blend_modes): axs[i].imshow(data, cmap='Reds', alpha=0.75, extent=(0, 0.8, 0, 0.8)) axs[i].imshow(data[::-1, :], cmap='Blues', alpha=0.75, extent=(0.2, 1, 0.4, 1.2), blend_mode=blend_mode) axs[i].pcolormesh(*np.meshgrid(np.linspace(0.6, 0.9, 5), np.linspace(0.7, 1, 5)), data[:5, :5], cmap='Spectral', alpha=0.75, shading='gouraud', blend_mode=blend_mode) axs[i].text(0.05, 0.15, "Horizontal", weight="bold", color="c", blend_mode=blend_mode) axs[i].text(0.35, 0.10, "Tilted", weight="bold", color="m", rotation=45, blend_mode=blend_mode) axs[i].plot([0.1, 0.1, 0.1, 0.1, 0.2, 0.2, 0.2, 0.2], [0.7, 0.8, 0.9, 1, 0.7, 0.8, 0.9, 1], 'p', markersize=15, markeredgecolor="orange", markerfacecolor="purple", alpha=0.75, blend_mode=blend_mode) axs[i].plot([0, 1], [1.2, 0], color="y", blend_mode=blend_mode) circ = Circle((.65, 0.5), .3, facecolor='g', alpha=0.5, blend_mode=blend_mode, zorder=2) axs[i].add_artist(circ) rect = Rectangle((0, 1.2), 1, .3, facecolor='lightgray', clip_on=False) axs[i].add_artist(rect) axs[i].set_title(blend_mode) plt.show()
Put off to future work:
pcolormesh.snap behaves when the mesh edges are not horizontal/verticalcontourf()/pcolor()/pcolormesh() to be True
Sorry, something went wrong.
There was an error while loading. Please reload this page.
dee65fa to
37b0b9c
Compare
|
This looks interesting. Thanks for working on it. Since I’m not into the topic I can dare to ask the stupid questions:
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Yup, that is correct: the history of how that "background" was constructed has no bearing on how the next Artist is blended in using its specific blend mode. It's also important to remember that that the "empty" background of an Axes is solid white, and thus not actually empty as far as these blend modes are concerned. For example, using "screen" to blend in an image on a truly empty background will just return the image, but on a white background will return solid white, which can make it look instead like the image call failed. That's why I turn off the face colors in my example above. What I still need to investigate is how my changes interact with collections of Artists. A user may want "over" blending (the default) within the collection before using a different blend mode for the collection as a whole.
Yes. In principle, the transformation functions for the hue/saturation/color/luminosity operators could have more than one possibility, but in practice I think everyone has simply used the same functions for decades (as defined in the PDF specification). |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
37b0b9c to
bb554e7
Compare
2221d69 to
6d49bcf
Compare
There was an error while loading. Please reload this page.
|
This is pretty cool :-)
Actually I suspect that another possibility is to want some nonstandard blending between multiple artists, then "over" blending of the result over the background. In general I suspect this would be related to adding support for temporary, intermediate rendering buffers, which is also something that would be useful for other purposes e.g. contour label overplotting (#26971 (comment)). |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
By the way, I decided to rename "over" to "normal". That mode of blending is referred to as "normal" often enough, and it makes it readily apparent to users that it is the standard choice (and the default). |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
6d49bcf to
63f53c9
Compare
63f53c9 to
c9552d5
Compare
f49e8d0 to
f7af1e4
Compare
f7af1e4 to
d313054
Compare
d04f663 to
c287d35
Compare
|
I have moved the fixes for contourf and pcolor/pcolormesh out of this PR to make this PR slightly more wieldy to review. The bugs are less apparent to users because it requires antialiasing to be turned on, which is not the default. I'll PR those fixes after this PR is merged. I have retained the fix to Agg Gouraud shading because the bug is easier to be encountered by users and would be immediately seen in the blend-mode gallery. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
Also, do you want to squash merge this when complete? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
This PR feels too hefty to be a single commit. Once the PR is approved, my inclination is to squash the review-triggered commits back into the first ~10 commits in the appropriate places. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Minor clarification on knockout and a bit confused on blend modes but otherwise this is awesome and thanks for your patience. Also sorry for the delay in getting back to you.
Also you might wanna make a blending mode :mpl_type:
matplotlib/lib/matplotlib/sphinxext/roles.py
Line 129 in e519c44
| def _mpltype_role(name, rawtext, text, lineno, inliner, options=None, content=None): |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Done!
I have now done this, so this PR is ready for (non-squashed) merging. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| Blending and compositing groups of artists | ||
| ========================================== | ||
|
|
||
| An advanced technique of blending artists (see :ref:`blend-modes`) is to use a |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Just a suggestion, but since blend groups is an advanced topic depending on blend modes, I'd suggest making this a subsection of an overall "blend modes and groups" page with two subsections.
I'm not sure a reader who doesn't know these terms would know which of these to drill down into.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I think it's fine as is b/c @ayshih structured it so the blend_modes page comes first in the order.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Congrats @ayshih! Appveyor and wasm failures are unrelated. Discussed on call and decided that doc changes can happen in follow ups as there are arguments for both approaches. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Thanks for the reviews and merge! |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
[Bug]: diagonal lines in pcolormesh with Gouraud shading and transparency Alternative compositing methods
There was an error while loading. Please reload this page.