I have a matplotlib contour plot of wind speed (m/s) with contour labels using clabel. Unfortunately, the default clabel locations are poorly placed - see the top right corner:
I would like to change this to make the plot easier to read.
I understand how to manually set the contour labels from the second response to this post.
However, I have so many contours and multiple figures that it seems like a very impractical solution to do this manually. Is there a non-manual way to clean up the contour label locations? Also, could I have more than one contour label per contour without doing it manually?
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?
I have drawn a trajectory plot in python using matplotlib of a boat like so:
Now I want to add some arrows, like wind direction, true heading etc. However I want the arrows to have the same size no matter which zoom-level the plot is at. I tried matplotlib.pyplot.arrow, however there I have to define the length of the arrows. I could make matplotlib.pyplot.arrow work, but then I'd have to get the height and width of the plot, and scale my arrows accordingly, so I wondered if there was a better way to obtain scale-independent arrows for these points?
You want to use matplotlib.axes.Axes.annotate instead. See the docs for more info!
Basically, set the xycoords parameter to "axes fraction" to instruct it to plot using relative fraction of the axes itself rather than data coordinates.
I'm combining a contour plot and an imshow. Depending on the colormap and the data, it sometimes happens that the contour labels have a color very similar to the pixmap and are therefore hard to read.
I remember seeing a matplotlib contour demo that showed how the text labels could be surrounded with a little white halo so as to make them readable regardless of the background, but I can't find it anymore. Does anyone know how to do that?
roadrunner66's answer worked, but it was not the halo effect I was looking for. However, I finally found it. You can use PathEffects as shown here:
http://matplotlib.org/examples/pylab_examples/patheffect_demo.html
I'm creating a plot with factorplot and then trying to add a subplot on top of each box. How can I get the x-axis locations of each individual box in the factor plot to put another line on top?
Maybe there's a way to get all the x-axis values of each box plot on the axes?
Here's my basic factor plot:
I want to add 1 subplot (the circle) in the middle of each box plot. However, I cannot figure out how to get the x-value of each box to properly space the points.
I see a lot of code for positions and offsets in the seaborn source that lays these out. However, I'm wondering if there is a more straight-forward method to get this information or at least approximate it.
As per #mwaskom's comments, you can use sns.stripplot() (and now also sns.swarmplot()) to include your data points with a data summary plot such as a box or violinplot.
Why does the following happen when using matplotlib and basemap to plot a simple polygon collection and 3D bars. Using how it says to create these type of plots here one can create this sort of plot.
However, what's interesting is that if instead you do not zoom "all" the way in to focus on a specific set of bars they appear to be off-center although they aren't really. This results from the polygons being tilted and the bars remaining stationary I assume. Whenever tilting / rotating the plot the polygons will be moved to face over the bars and this is rather annoying as it ruins the look of the plot imo.
Does anyone know how to avoid this / fix this problem? I've included some sample images to describe this behavior.
This is probably not the best way to resolve this and if anyone has a better method please share.
I've found that a very simple way to get around the polygons going over the bars and creating this offset look is to simply make the polygon collection have a high transparency factor. Unfortunately, this also takes away the face color set to the polygons, and this is why I dislike this as a solution as you can no longer have a wide range of options manipulating the face / edge colors. The result is the following difference:
The bars i've created also have an alpha option set to alpha = 0.5 that can of course be changed if anyone was wondering why they appeared to be so transparent.
Without manipulating the alpha option in a polygon collection such as the following
map = Basemap()
figure = plot.figure()
axes = Axes3D(figure)
for polygon in map.landpolygons:
polygons.append(polygon.get_cords())
#alpha = 0-1 in the below 1 highest 0 lowest
collection = PolyCollection(polygons, closed = False)
axes.add_collection3d(collection)
results in the following
giving an alpha option of 0 in collection = PolyCollection(polygons, alpha = 0, closed = False) results in the following
As an interesting aside with an alpha option set to alpha = 0.4 you can see where the polygons created start to overlap the bars