Giter Club home page Giter Club logo

Comments (7)

AgilentGCMS avatar AgilentGCMS commented on June 15, 2024

It seems like shading='gouraud' does not produce this moire pattern. However, I cannot use gouraud shading with a colormap having transparency because of this issue in matplotlib (I have tried).

from cartopy.

greglucas avatar greglucas commented on June 15, 2024

The pcolormesh cells are not straight up and down along a line of pixels like they are in the PlateCarree projection. So the patches are aliased and have to blend between adjacent pixels which causes this. If you zoom in you can see the jagged edges of the lines where one cell patch touches another along its edges.
image
If you save it as a pdf it looks slightly better, but you can zoom in and see that even the pdf has issues where the patches touch. I'm going to close this issue in Cartopy because there is nothing we can do here, and I'm pretty sure this can be reproduced upstream in matplotlib by drawing angled lines with pcolormesh. There is a good image in this PR of the different combinations of options and ideas to try for your case though: matplotlib/matplotlib#16090

from cartopy.

AgilentGCMS avatar AgilentGCMS commented on June 15, 2024

@greglucas I understand why this is happening, but when two patches touch, why is the blended color different from either patch color? I suspect it's because the blended edge color does not match the alpha value of either patch.

from cartopy.

greglucas avatar greglucas commented on June 15, 2024

See this thread and linked issues for lots of discussion and ideas on this: matplotlib/matplotlib#5694

Part of the issue is what canvas/background you're putting the "50% of a stroke" into. I think it is generally an all-white background that the aliasing gets done with, but that may have changed recently. So maybe you could even set the background transparent first to try and avoid that specific white blending? (I haven't tried that at all)

from cartopy.

AgilentGCMS avatar AgilentGCMS commented on June 15, 2024

@greglucas Thank you for engaging with me, and for the suggestions. Unfortunately, most of the discussion at matplotlib/matplotlib#5694 went over my head; I confess that I'm primarily a user and unaware of the black magic that goes on under the hood.

My ultimate goal is to make plots that can go into making a movie such as this one or this one. I don't know what they use for creating the images, but I can see no moire patterns or patch edges in any of the frames. Do I understand correctly that that is currently impossible using anything that depends on matplotlib? I've tried pcolor, pcolormesh and contourf, and all those create the edges in question when using colormaps with transparency.

from cartopy.

greglucas avatar greglucas commented on June 15, 2024

Unfortunately, at the moment I think that is right with the Agg backend. However, I just gave this a whirl with the mplcairo backend and it looks like that works as expected without the seams (there may still be some at the edges of the globe due to Cartopy using pcolor cells there).

There is some discussion here about the seams as well https://github.com/matplotlib/mplcairo#simplification-threshold
The bottom line is that the renderer needs to be aware of all the patches and not blend them one-by-one when matplotlib calls them. So you have to pass the right collection. QuadMesh should be able to do that and I think it may be an issue with the Agg backend.

So, my suggestion is to use mplcairo https://github.com/matplotlib/mplcairo if you can.

from cartopy.

AgilentGCMS avatar AgilentGCMS commented on June 15, 2024

Hooray... sort of. I tried the mplcairo backend, and while it works perfectly for Robinson projection (no seams), it doesn't work at all for Orthographic projection. As in, no colors whatsoever. Identical calls to pcolormesh for both. Here's the code I used:

from matplotlib import pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import numpy as np
import matplotlib.colors as m_colors

# create lat, lon and data arrays
lat_edges = np.linspace(-90., 90., 361)
lon_edges = np.linspace(-180., 180., 721)
lat_centers = 0.5*(lat_edges[1:]+lat_edges[:-1]) * np.pi/180.0 # convert to radian
lon_centers = 0.5*(lon_edges[1:]+lon_edges[:-1]) * np.pi/180.0 # convert to radian
lon_c, lat_c = np.meshgrid(lon_centers, lat_centers)
data = np.cos(2*lat_c) * np.sin(2*lon_c)

# create a colormap with transparency, that is blue for 0 and red for 1, with transparency in the middle
my_cmap=m_colors.LinearSegmentedColormap.from_list("", [(0,0,1,1), (1,1,1,0), (1,0,0,1)])

central_lat = 0.0
central_lon = 0.0
data_proj = ccrs.PlateCarree()

# First, orthographic projection
map_proj = ccrs.Orthographic(central_longitude=central_lon, central_latitude=central_lat)
aspect = (map_proj.x_limits[1]-map_proj.x_limits[0])/(map_proj.y_limits[1]-map_proj.y_limits[0])
height = 5.0
width  = height * aspect
fig = plt.figure(figsize=(width, height))
fig.set_facecolor('0.5')
plot_ax = plt.axes([0.,0.,1.,1.], projection=map_proj)
plot_ax.set_facecolor('k')

img = plot_ax.pcolormesh(lon_edges, lat_edges, data,
    transform=data_proj, cmap=my_cmap, vmin=-1, vmax=1, shading='flat')

# Now, Robinson
map_proj = ccrs.Robinson(central_longitude=central_lon)
aspect = (map_proj.x_limits[1]-map_proj.x_limits[0])/(map_proj.y_limits[1]-map_proj.y_limits[0])
height = 5.0
width  = height * aspect
fig = plt.figure(figsize=(width, height))
fig.set_facecolor('0.5')
plot_ax = plt.axes([0.,0.,1.,1.], projection=map_proj)
plot_ax.set_facecolor('k')

img = plot_ax.pcolormesh(lon_edges, lat_edges, data,
    transform=data_proj, cmap=my_cmap, vmin=-1, vmax=1, shading='flat')

# show all
plt.show()

The plot with Robinson projection gave me what I was hoping for, no seams, the background black showing through according to transparency.
moire_robinson
The plot with Orthographic projection, however, was totally black.
moire_orthographic

from cartopy.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.