I want to use a basemap figure as a background and plot things ontop. As the generation of the basemap figure (a polar stereographic plot) is quite time intensive I only want to do this once.
The second step would be to draw some wind barbs on this plot and some other wind barbs on the same plot, but without the first set of barbs.
Now either I copy the background image and then draw two different images or I can remove the first set of barbs and then draw the second, I don't mind which way to go.
Unfortunately my brain is not helping me today and I am getting nowhere. I would be grateful for any tips.
If the new barbs will be in the same place you can use set_UVC to update the existing object with the new wind data.
Assuming m is your basemap object, something like:
n_barb,s_barb = m.barbs(...)
#some code
n_barb.set_UVC(newU,newV,newC)
I don't have wind data to test this on though.
Related
I have been trying to plot Exclusive Economic Zone (EEZ) shapefiles on an orthographic projection from the basemap package. However, the shapefile file has EEZs from around the world, and so when I try to plot the shapefiles there are always some that are not visible in the projection at that particular angle. This results in the shapes being smeared out, which is not quite the effect that I am going for. Ultimately I wish to only plot select shapefiles, but then this same issue will likely pop up so for now I'd be happy to solve this more basic case where I try to plot all of them.
Here in the code I try a simple case where I plot the shapefiles with the readshapefile command from basemap. I have also tried plotting the various shapes as polygons (figured that would give me more flexibility in changing the appearances of the individual shapefiles) but then I could not get the polygons to appear on the map in the right spot and I would see similar smearing behavior (so likely the issue has the same or a similar root cause).
I have attached the code from the simple case below. If I run this, I get the projection to appear as a I want, but with the smearing of the shapefiles. The shapefiles can be found at http://www.marineregions.org/downloads.php#unioneezcountry where I use version 2 of Marine and land zones: the union of world country boundaries and EEZ's.
#Here is the figure
fig=plt.figure(figsize=(20,12))
ax=fig.add_subplot(111)
#create the map projection
Map=Basemap(projection='ortho',lon_0=0,lat_0=0,resolution='l')
Map.drawcoastlines(zorder=10)
Map.drawcountries(zorder=10)
Map.drawmapboundary()
#Reading in the shapefile and plotting it
Map.readshapefile('~/EEZ_Boundaries/EEZ_land_v2_201410','countries')
Here is a link to the image I get when I run the code
Ok, so after more time of trying to get this to work, I have pretty much given up with Basemap and made a (long overdue) switch to cartopy. In that case, the problem does solved by Cartopy already, so the code that creates the figure I was trying to get is:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cpf
from cartopy.io.shapereader import Reader
#Set the projection
projection=ccrs.Orthographic(central_longitude=0,central_latitude=0)
fig=plt.figure(figsize=(20,12))
axMap=fig.add_subplot(1,1,1,projection=projection)
#resolution of the coastlines
resolution='10m'
axMap.coastlines(resolution=resolution,edgecolor='black',zorder=10)
#Add the shapefiles
shape_feature = cpf.ShapelyFeature(Reader(direc_shp+file_shp).geometries(),
ccrs.PlateCarree(), edgecolor='black')
axMap.add_feature(shape_feature,zorder=1)
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?
I am working on a few of my meteorology plots and I am trying to make them a little more visually friendly. The polar plot is called a hodograph and plots the windspeed vectors with increasing height. I want to make it so that the lowest 3 kilometers of data is say red, then 3-6km is say blue and such. Ive looked at possibly building my own coolor map but I am not sure how to go about implementing that. Any help would be much appreciated. Ive included a few screenshots and the basic hodograph code. The data used is simply an array with several columns: temperature, wind speed, wind direction, dewpoint, height in meters, ect.
#begin hodograph subplot
ax1 = fig.add_subplot(122,polar = True)
ax1.set_theta_offset(np.pi/2)
ax1.set_theta_direction(-1)
ax1.plot(wd,ws,'ro-')
I was able to figure out with help from a friend how to loop over that data and separate it with a loop. Once separated, each line segment gets plotted independently.
How can I save Python plots at very high quality?
That is, when I keep zooming in on the object saved in a PDF file, why isn't there any blurring?
Also, what would be the best mode to save it in?
png, eps? Or some other? I can't do pdf, because there is a hidden number that happens that mess with Latexmk compilation.
If you are using Matplotlib and are trying to get good figures in a LaTeX document, save as an EPS. Specifically, try something like this after running the commands to plot the image:
plt.savefig('destination_path.eps', format='eps')
I have found that EPS files work best and the dpi parameter is what really makes them look good in a document.
To specify the orientation of the figure before saving, simply call the following before the plt.savefig call, but after creating the plot (assuming you have plotted using an axes with the name ax):
ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
Where elevation_angle is a number (in degrees) specifying the polar angle (down from vertical z axis) and the azimuthal_angle specifies the azimuthal angle (around the z axis).
I find that it is easiest to determine these values by first plotting the image and then rotating it and watching the current values of the angles appear towards the bottom of the window just below the actual plot. Keep in mind that the x, y, z, positions appear by default, but they are replaced with the two angles when you start to click+drag+rotate the image.
Just to add my results, also using Matplotlib.
.eps made all my text bold and removed transparency. .svg gave me high-resolution pictures that actually looked like my graph.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
# Do the plot code
fig.savefig('myimage.svg', format='svg', dpi=1200)
I used 1200 dpi because a lot of scientific journals require images in 1200 / 600 / 300 dpi, depending on what the image is of. Convert to desired dpi and format in GIMP or Inkscape.
Obviously the dpi doesn't matter since .svg are vector graphics and have "infinite resolution".
You can save to a figure that is 1920x1080 (or 1080p) using:
fig = plt.figure(figsize=(19.20,10.80))
You can also go much higher or lower. The above solutions work well for printing, but these days you want the created image to go into a PNG/JPG or appear in a wide screen format.
Okay, I found spencerlyon2's answer working. However, in case anybody would find himself/herself not knowing what to do with that one line, I had to do it this way:
beingsaved = plt.figure()
# Some scatter plots
plt.scatter(X_1_x, X_1_y)
plt.scatter(X_2_x, X_2_y)
beingsaved.savefig('destination_path.eps', format='eps', dpi=1000)
In case you are working with seaborn plots, instead of Matplotlib, you can save a .png image like this:
Let's suppose you have a matrix object (either Pandas or NumPy), and you want to take a heatmap:
import seaborn as sb
image = sb.heatmap(matrix) # This gets you the heatmap
image.figure.savefig("C:/Your/Path/ ... /your_image.png") # This saves it
This code is compatible with the latest version of Seaborn. Other code around Stack Overflow worked only for previous versions.
Another way I like is this. I set the size of the next image as follows:
plt.subplots(figsize=(15,15))
And then later I plot the output in the console, from which I can copy-paste it where I want. (Since Seaborn is built on top of Matplotlib, there will not be any problem.)
I'm trying to animate a bunch of constantly updating points over an image (imagine making a plotted dot move diagonally across some image). I've looked at the animate examples here: http://matplotlib.org/examples/animation/dynamic_image.html, but I'm not sure how to keep the same image while clearing out all previous dots, then redrawing them. Any ideas?
You do not need to clear the figure between every frame
#initial data
ln, = ax.plot(x,y)
#...some loop code
ln.set_xdata(new_x)
ln.set_ydata(new_y)
Can you show some code of what you have tried, it will make it easier to give a more concrete answer.
Also see: using matplotlib's quiver in a loop efficiently, Visualization of 3D-numpy-array frame by frame