I plotted a geographic map with datashader. Everything works fine, however the geographic projection seems to be incorrect. The lengths and aspect ratios do not match, probably because no geographical projection is set?
My Code looks like this:
agg = ds.Canvas().points(df, 'lon',"lat")
karte=ds.tf.set_background(ds.tf.shade(agg, cmap=cc.fire,how="log"), "black")
utils.export_image(img=karte,filename='output', fmt=".png", background=None)
That's a nice-looking amoeba! :-)
Datashader is a general-purpose tool, not tied to geographical data in any way. In particular, if you want the data to be projected into some other coordinate system, you need to project it before calling Datashader; all Datashader does is render what it is given.
Datashader does include one utility function for the special case of projecting lon/lat data into Web Mercator (datashader.utils.lnglat_to_meters), for convenience with plotting libraries that use Web Mercator mapping tiles, but if you are visualizing the data on its own (not overlaid on a map) you shouldn't even need that utility; bare lon/lat values should be ok.
If you want some specific aspect ratio, you can determine it with parameters to the Canvas constructor. Specifically, set set the plot_height and plot_width to whatever image size you want, then set x_range and y_range to the ranges of data space you want in that image size (e.g. longitude and latitude ranges like xrange=(270, 290), yrange=(30,40)).
Or you can use the high-level interfaces at hvplot.holoviz.org or holoviews.org to overlay onto a map, which will force a geographic aspect ratio.
Related
I'm not sure whether this is a Cartopy or Matplotlib question, so I apologize if this would have been better suited for Matplotlib.
I am transitioning from NCL (NCAR Command Language https://www.ncl.ucar.edu/) to Python. Previously, I was using NCL to contour with a method of "CellFill" (https://www.ncl.ucar.edu/Document/Graphics/Resources/cn.shtml#cnFillMode). In Python, I am using pcolormesh to render a gridded dataset with a horizontal grid spacing of 3-km. In NCL, regardless of whether I am plotting the full domain or an area zoom, the resolution of the resulting image appears to be consistent using a PNG output. In Python however, if I use pcolormesh with an area zoom it looks identical to my NCL plot but if I try and plot the full domain, it looks different.
I've traced this down to the figure resolution. At the full domain view in Python, however I have my figure settings configured causes the 3-km cells in certain areas to become "blurred together" making it appear as if the entire region is a certain contour value when in actuality there are areas with no values in between.
Here is a CONUS example of pcolormesh:
And here is a full CONUS version from NCL:
There are several areas of note, but one obvious area is the NM/AZ region. If I zoom in very closely in both Python and NCL in this region, the resulting images look identical. But at the CONUS view it looks like there's much more shading in this area than there actually should be in the Python version.
crs = ccrs.PlateCarree() # Lat/Lon
fig = plt.figure(1, figsize=(15, 15))
ax.add_feature(cfeature.COASTLINE.with_scale('50m'), linewidth=BORDERWIDTH,edgecolor=BORDERCOLOR)
ax.add_feature(cfeature.STATES, linewidth=BORDERWIDTH,edgecolor=BORDERCOLOR)
ax.add_feature(cfeature.BORDERS, linewidth=BORDERWIDTH,edgecolor=BORDERCOLOR)
ax1 = plt.subplot(111,projection=crs)
norm = BoundaryNorm(LEVELS,ncolors=plt.get_cmap('plasma').N,clip=False)
cf1 = ax1.pcolormesh(diffsum.lon0,diffsum.lat0,diffsum,cmap='plasma',transform=ccrs.PlateCarree(),norm=norm)
plt.savefig('testing%s.png' % (DSTRING))
Note that if I manually increase the DPI used in the resulting image to something rediculous like 1000, or increase the figure size to 100x100 inches, it also looks OK but the resulting image is so gigantic it makes it cumbersome to view on the screen.
Is there something I am missing about pcolormesh that I should be doing to help better adapt the resolution of the cells being shaded with respect to the resolution of the actual figure itself?
With the supporting of matplotlib basemap, I can draw my netCDF files in different kind of projection type.
We always see the figure is in rectangular showing like this:
But I also see some figures showing like:
For now, I have some weather simulation data and I want to represent it on the map with Lambert projection.
The temperature of on time slice shows like:
So, here is my question:
How to generate the figure which the borders of the canvas fit the lcc projection like the previous one using Basemap?
In the very near future I will be doing some analysis of measurement data. This data is geographical data (e.g. height measurements and wind measurements) which has a high resolution (some 50 million x, y, and z points for example). Plotting such a dataset is very slow in matplotlib and I wonder if there are better options.
The plots I see myself creating in the near future would be a quiver plot (for the winddirections) and color plots for terrain heights. It must be noted that the x, y and z values do not line up to be a square or rectangular grid.
Besides creating figures it is likely that the dataset will also need to be shown on google maps. Would this be possible as an overlay (also with such a large dataset or would I need to overlay an image?)
You could consider using PyQt and its Graphics Framework.
You would define classes for each type of item, inheriting from QGraphicsItem, then you just add these items to a QGraphicsScene, and leave the rendering itself to QGraphicsView. This is expected to be very performant.
As for Google Maps, you can export a subset of your data to KML, and render it using a KmlLayer, or you can use an ImageOverlay as you said, or else you can try the DataLayer API.
(As an alternative, you can embed a QWebKit widget pointing to GoogleMaps and overlay a QGraphicsView over it, but I think that would be a bit overkill).
I am trying to use the coastline data provided by Natural Earth (in the form of shape files) within basemap. I am getting weird horizontal lines as shown in the figures below. When the plot is centered on 180 degree longitude, the number of such lines increases.
Looking at the location of these lines (which is where continents wrap around), I reckon the source of the problem must be related to how the polygons are defined in the shape file and the wrapping of the polygon around a longitude, but I don't see how I can go about fixing it. I would expect a mapping library like basemap to be able to handle this transparently. Any solution would very be helpful.
I am using the "ne_110m_coastline" data from Natural Earth and I have not modified it in any way. Here's a sample code that replicates the problem:
Map = Basemap(projection='eck4',lon_0=0, resolution='c')
a = Map.readshapefile("ne_110m_coastline", "coast")
I often find myself needing to create heatmap-style visualizations in Python with matplotlib. Matplotlib provides several functions which apparently do the same thing. pcolormesh is recommended instead of pcolor but what is the difference (from a practical point of view as a data plotter) between imshow and pcolormesh? What are the pros/cons of using one over the other? In what scenarios would one or the other be a clear winner?
Fundamentally, imshow assumes that all data elements in your array are to be rendered at the same size, whereas pcolormesh/pcolor associates elements of the data array with rectangular elements whose size may vary over the rectangular grid.
If your mesh elements are uniform, then imshow with interpolation set to "nearest" will look very similar to the default pcolormesh display (without the optional X and Y args). The obvious differences are that the imshow y-axis will be inverted (w.r.t. pcolormesh) and the aspect ratio is maintained, although those characteristics can be altered to look like the pcolormesh output as well.
From a practical point of view, pcolormesh is more convenient if you want to visualize the data array as cells, particularly when the rectangular mesh is non-uniform or when you want to plot the boundaries/edges of the cells. Otherwise, imshow is more convenient if you have a fixed cell size, want to maintain aspect ratio, want control over pixel interpolation, or want to specify RGB values directly.