Reduce the Size of Matplotlib Basemap - python

In various operational and manually-run Python scripts, I produce thousands of plots of California every day using matplotlib's Basemap:
mp = Basemap(width=1284000,height=1164000,projection='lcc',lat_1=30.,lat_2=60,\
lat_0=37,lon_0=-120.5,resolution='c',rsphere=6370000.00)
# fill data: lats, lons, grid
cs = orb.pcolor(lons,lats,grid,cmap=cm.jet,norm=colors.LogNorm(),latlon=True)
mp.drawcounties()
However, I lose dozens of hours of computing time every single day to loading these large basemaps that cover the entire world. All I need is the counties in California, but I end up loading all the counties in the world into memory. I love how flexible this library is, but it is officially too slow.
How could I produce these maps faster?
Could I somehow create a cropped version of the matplotlib Basemap, with only California?
Is there a faster, non-matplotlib way to create geo-referenced plots?

How could I produce these maps faster?
You are already using the lowest resolution ("c"). You can change the "area_thresh" argument, but I don't think that'll help much. You'll probably have to work on the way you're plotting the data itself.
Could I somehow create a cropped version of the matplotlib Basemap, with only California?
You can download a custom map of California and plot only that. Basemap comes with basic world maps, but you can use maps from other sources. It should be easy to get one googling "california shapefile". Use the "readshapefile" method in mpl_toolkits.basemap to load it.
This notebook shows how to work with readshapefile and with an alternative method (the pyshp module).
Is there a faster, non-matplotlib way to create geo-referenced plots?
I've heard good things about Vincent, but I haven't tried it myself.

Related

How can I speed up mplot3d's render?

I'm visualizing timestamped xy positions of objects using mplot3d. I would like to rotate and zoom into the resulting figure to better understand the details. Python is really slow at rendering the figure, making it almost impossible to do what I want. Is there a way to make the 3d-plot faster to manipulate (GPU acceleration, wireframe, etc.)?
An option may be to use MayaVi, which is recommended by mplot3d itself:
http://matplotlib.org/mpl_toolkits/mplot3d/faq.html#how-is-mplot3d-different-from-mayavi
(in fact "highly recommended")

Matplotlib alternative for 3D scatter plots

I am having a hard time using Matplotlib to visualize reprojection results of my data in 3 dimensions after applying Principle components analysis or Linear discriminant analysis. After doing a scatter plot, I cannot rotate the data or change the point of view while zooming easily (Rotation axis stays the same even after you zoom, and if you zoom too much points just disappear) and every change takes one second to occur. Matplotlib is very useful but for this specific use case it starts to get very frustrating as it probably wasn't designed for such tasks. Is there an alternative to Matplotlib in Python that can handle 3d scatter plots better and where one could fluidly navigate through the cloud?
An example is shown in the next figure. I have drawn spheres around each data cluster corresponding to a specific class and colored overlapping spheres with red. Now I want to see how these sphere intersect. I think the biggest problem with Matplotlib is that it doesn't allow shifting of the whole graph with the mouse, it only allows rotation around a fixed point, which makes things very messy once you zoom a bit.
matplotlib is not quite mature for 3d graphics :
http://matplotlib.org/mpl_toolkits/mplot3d/faq.html
mplot3d was intended to allow users to create simple 3D graphs with the same “look-and-feel” as matplotlib’s 2D plots. Furthermore, users can use the same toolkit that they are already familiar with to generate both their 2D and 3D plots.
I don't think easy navigation in a 3d plot is easily doable (even 3d scaling is not possible without tweaking the lib). mplot3d was not really intended to be a full-fledged 3D graphics library in the beginning, but more a nice addition for people who needed basic 3D and who were acquainted with matplotlib 2D plot structure.
You might want to take a look at MayaVI (which is pretty good) :
MayaVi2 is a very powerful and featureful 3D graphing library. For advanced 3D scenes and excellent rendering capabilities, it is highly recomended to use MayaVi2.
Note that unlike matplotlib, MayaVI is not yet compatible with Python3 (and might not be in the foreseeable future), so you'll need a Python2 installation.
A very good alternative, but not in Python, is the 3D plot from ILNumerics (http://ilnumerics.net/). It is in .NET
Matplotlib works alright for 3D however, not too fast when interactivity is needed:
https://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html
Mayavi is really fast and compatible with Python 3:
https://docs.enthought.com/mayavi/mayavi/mlab.html#id1

Density plots from matlab to matplotlib

Since some years ago I use matlab for my plots (mostly density plots), but now I want to change to matplotlib. I have a problem trying to figure out how to get analogous plots in matplotlib. I have to represent a 2D array. In matlab I used to use the surf function, and then change to view(2) (az=0 and el=90). An example:
surf(X,Y,log10(z),'FaceColor','interp','EdgeColor','none')
view(2)
In matplotlib I have tried some functions, but I have not got the same feeling. m3plot is a computationally expensive toolkit and it is not the same as using surf. imshow does not allow to use log functions in his arguments (like the example), and log values is something mandatory for me. Then it is pcolor, but I can not find a 'FaceColor'-like option to smooth the edges. I would like to know if someone knows what is the best equivalent in matplotlib.
Thank you for your time!
Try installing mayavi which has the surf function (mayavi is a fully-blown 3D visualisation library using hardware acceleration)
Finally, the solution that suits me is to use the routine pcolormesh(). This combined with the option shading='gouraud' interpolates the data and smooth the edges. In addition, it works pretty well with large arrays in comparision with pcolor.

Barchart (o plot) 3D in Python

I need to plot some data in various forms. Currently I'm using Matplotlib and I'm fairly happy with the plots I'm able to produce.
This question is on how to plot the last one. The data is similar to the "distance table", like this (just bigger, my table is 128x128 and still have 3 or more number per element).
Now, my data is much better "structured" than a distance table (my data doesn't varies "randomly" like in a alphabetically sorted distance table), thus a 3D barchart, or maybe 3 of them, would be perfect. My understanding is that such a chart is missing in Matplotlib.
I could use a (colored) Countor3d like these or something in 2D like imshow, but it isn't really well representative of what the data is (the data has meaning just in my 128 points, there isn't anything between two points). And the height of bars is more readable than color, IMO.
Thus the questions:
is it possible to create 3D barchart in Matplotlib? It should be clear that I mean with a 2D domain, not just a 2D barchart with a "fake" 3D rendering for aesthetics purposes
if the answer to the previous question is no, then is there some other library able to do that? I strongly prefer something Python-based, but I'm OK with other Linux-friendly possibilities
if the answer to the previous question is no, then do you have any suggestions on how to show that data? E.g. create a table with the values, superimposed to the imshow or other colored way?
For some time now, matplotlib had no 3D support, but it has been added back recently. You will need to use the svn version, since no release has been made since, and the documentation is a little sparse (see examples/mplot3d/demo.py). I don't know if mplot3d supports real 3D bar charts, but one of the demos looks a little like it could be extended to something like that.
Edit: The source code for the demo is in the examples but for some reason the result is not. I mean the test_polys function, and here's how it looks like:
example figure http://www.iki.fi/jks/tmp/poly3d.png
The test_bar2D function would be even better, but it's commented out in the demo as it causes an error with the current svn version. Might be some trivial problem, or something that's harder to fix.
MyavaVi2 can make 3D barcharts (scroll down a bit). Once you have MayaVi/VTK/ETS/etc. installed it all works beautifully, but it can be some work getting it all installed. Ubuntu has all of it packaged, but they're the only Linux distribution I know that does.
One more possibility is Gnuplot, which can draw some kind of pseudo 3D bar charts, and gnuplot.py allows interfacing to Gnuplot from Python. I have not tried it myself, though.
This is my code for a simple Bar-3d using matplotlib.
import mpl_toolkits
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
%matplotlib inline
## The value you want to plot
zval=[0.020752244,0.078514652,0.170302899,0.29543857,0.45358061,0.021255922,0.079022499,\
0.171294169,0.29749654,0.457114286,0.020009631,0.073154019,0.158043498,0.273889264,0.419618287]
fig = plt.figure(figsize=(12,9))
ax = fig.add_subplot(111,projection='3d')
col=["#ccebc5","#b3cde3","#fbb4ae"]*5
xpos=[1,2,3]*5
ypos=range(1,6,1)*5
zpos=[0]*15
dx=[0.4]*15
dy=[0.5]*15
dz=zval
for i in range(0,15,1):
ax.bar3d(ypos[i], xpos[i], zpos[i], dx[i], dy[i], dz[i],
color=col[i],alpha=0.75)
ax.view_init(azim=120)
plt.show()
http://i8.tietuku.com/ea79b55837914ab2.png
You might check out Chart Director:
http://www.advsofteng.com
It has a pretty wide variety of charts and graphs and has a nice Python (and several other languages) API.
There are two editions: The free version puts a blurb on the generated image, and the
pay version is pretty reasonably priced.
Here's one of the more interesting looking 3d stacked bar charts:
(source: advsofteng.com)

Scientific Plotting in Python

I have a large data set of tuples containing (time of event, latitude, longitude) that I need to visualize. I was hoping to generate a 'movie'-like xy-plot, but was wondering if anyone has a better idea or if there is an easy way to do this in Python?
Thanks in advance for the help,
--Leo
get matplotlib
The easiest option is matplotlib. Two particular solutions that might work for you are:
1) You can generate a series of plots, each a snapshot at a given time. These can either be displayed as a dynamic plot in matplotlib, where the axes stay the same and the data moves around; or you can save the series of plots to separate files and later combine them to make a movie (using a separate application). There a number of examples in the official examples for doing these things.
2) A simple scatter plot, where the colors of the circles changes with time might work well for your data. This is super easy. See this, for example, which produces this figure
alt text http://matplotlib.sourceforge.net/plot_directive/mpl_examples/pylab_examples/ellipse_collection.hires.png
I'd try rpy. All the power of R, from within python.
http://rpy.sourceforge.net/
rpy is awesome.
Check out the CRAN library for animations,
http://cran.r-project.org/web/packages/animation/index.html
Of course, you have to learn a bit about R to do this, but if you're planning to do this kind of thing routinely in future it will be well worth your while to learn.
If you are interested in scientific plotting using Python then have a look at Mlab: http://code.enthought.com/projects/mayavi/docs/development/html/mayavi/mlab.html
It allows you to plot 2d / 3d and animate your data and the quality of the charts is really high.
Enthought's Chaco is designed for interactive/updating plots. the api and such takes a little while to get use to, but once you're there it's a fantastic framework to work with.
I have had reasonable success with Python applications generating SVG with animation features embedded, but this was with a smaller set of elements than what you probably have. For example, if your data is about a seismic event, show a circle that shows up when the event happened and grows in size matching the magnitude of the event. A moving indicator over a timeline is really simple to add.
Kaleidoscope (Opera, others maybe, Safari not) shows lots of pieces moving around and I found inspirational. Lots of other good SVG tutorial content on the site too.
You might want to look at PyQwt. It's a plotting library which works with Qt/PyQt.
Several of the PyQwt examples (in the qt4examples directory) show how to create "moving" / dynamically changing plots -- look at CPUplot.py, MapDemo.py, DataDemo.py.

Categories

Resources