get numpy array of matplotlib tricontourf - python

I had x,y,height vars to build a contour in python.
I created a Triangulation grid using
x,y,height and traing are numpy arrays
tri = Tri.Triangulation(x, y, triang)
then i did a contour using tricontourf
tricontourf(tri,height)
how can i get the output of the tricontourf into a numpy array. I can display the image using pyplot but I dont want to.
when I tried this:
triout = tricontourf(tri,height)
print triout
I got:
<matplotlib.tri.tricontour.TriContourSet instance at 0xa9ab66c>
I need to get the image data and if I could get numpy array its easy for me.
Is it possible to do this?
if its not possible can I do what tricontourf does without matplotlib in python?

You should try this :
cs = tricontourf(tri,height)
for collection in cs.collections:
for path in collection.get_paths():
print path.to_polygons()
as I learned on:
https://github.com/matplotlib/matplotlib/issues/367
(it is better to use path.to_polygons() )

Related

How to retrieve seaborn's histplot data [duplicate]

I use
sns.distplot
to plot a univariate distribution of observations. Still, I need not only the chart, but also the data points. How do I get the data points from matplotlib Axes (returned by distplot)?
You can use the matplotlib.patches API. For instance, to get the first line:
sns.distplot(x).get_lines()[0].get_data()
This returns two numpy arrays containing the x and y values for the line.
For the bars, information is stored in:
sns.distplot(x).patches
You can access the bar's height via the function patches.get_height():
[h.get_height() for h in sns.distplot(x).patches]
If you want to obtain the kde values of an histogram you can use scikit-learn KernelDensity function instead:
import numpy as np
import pandas as pd
from sklearn.neighbors import KernelDensity
ds=pd.read_csv('data-to-plot.csv')
X=ds.loc[:,'Money-Spent'].values[:, np.newaxis]
kde = KernelDensity(kernel='gaussian', bandwidth=0.75).fit(X) #you can supply a bandwidth
#parameter.
x=np.linspace(0,5,100)[:, np.newaxis]
log_density_values=kde.score_samples(x)
density=np.exp(log_density_values)
array([1.88878660e-05, 2.04872903e-05, 2.21864649e-05, 2.39885206e-05,
2.58965064e-05, 2.79134003e-05, 3.00421245e-05, 3.22855645e-05,
3.46465903e-05, 3.71280791e-05, 3.97329392e-05, 4.24641320e-05,
4.53246933e-05, 4.83177514e-05, 5.14465430e-05, 5.47144252e-05,
5.81248850e-05, 6.16815472e-05, 6.53881807e-05, 6.92487062e-05,
7.32672057e-05, 7.74479375e-05, 8.17953578e-05, 8.63141507e-05,
..........................
..........................
3.93779919e-03, 4.15788216e-03, 4.38513011e-03, 4.61925890e-03,
4.85992626e-03, 5.10672757e-03, 5.35919187e-03, 5.61677855e-03])
With the newer version of seaborn this is not the case anymore. First of all, distplot has been replaced with displot. Secondly, when calling get_lines() an error message comes up AttributeError: 'FacetGrid' object has no attribute 'get_lines'.
This will get the kde curve you want
line = sns.distplot(data).get_lines()[0]
plt.plot(line.get_xdata(), line.get_ydata())

How to resize matrix like image in Python

How to resize a matrix in python, say np.random.randn(100,100), to shape [50,50]? I hope to get interpolation like what we expect for image resize, like cv2.imresize. But I don't find some decent way to do for matrix.
I think np.resize does't serve this purpose for it do no interpolation to keep the new matrix "looks" like the old one, using the plt.matshow().
import numpy as np
import matplotlib.pyplot as plt
a = np.random.randn(100,100)
# how to do?
b = resize(a, ) # something like this
plt.matshow(a)
plt.matshow(b)
plt.show()
--> a and b looks quite like but with different size

Plotting masked array that has been gridded using griddata

I have a 2D array of satellite data, and two corresponding 2D arrays giving the latitude and longitude of each pixel.
The data array is a masked array.
When I plot it up using pcolormesh, it looks like this:
m.pcolormesh(lon, lat, data)
I am attempting to grid this data on to a 0.25x0.25 deg grid.
lonGrid = arange(0, 360, 0.25)
latGrid = arange(-90, 90 0.25)
dataGridded = griddata(lon.ravel(),lat.ravel(),data.ravel(),latGrid,lonGrid, interp='linear')
m.pcolormesh(lonGrid, latGrid, dataGridded)
However, the resulting plot comes out as this:
It seems like this error has something to do with pcolormesh filling in the space between masked values. But I am unsure how to fix this.
Thanks
EDIT:
I was able to use the scipy version of griddata to get this to work...but its much slower and the syntax is more clunky. I would still appreciate some help getting the mpl(?) version above to work
from scipy.interpolate import griddata as griddata2
lonGrid,latGrid = meshgrid(lonGrid,latGrid)
dataGrid = griddata2((lon.ravel(),lat.ravel()),data.ravel(),(lonGrid,latGrid), method = 'linear')
dataGrid = ma.masked_where((dataGrid < 0) | isnan(dataGrid), dataGrid)
m.pcolormesh(lonGrid, latGrid, dataGridded)
Here are a couple initial troubleshooting ideas.
What version of Numpy are you using? If 1.09 or earlier the .ravel() will not return a masked array if given a masked array. See here.
The data array "wind" became "data". Is "data" truly masked? What happened between the two? Some more code would be useful.
dataGridded = griddata(lon.ravel(),lat.ravel(),XXXX.ravel(),latGrid,lonGrid, interp='linear')

Imshow and pcolor throw errors when trying to create test pattern-style bars

I am trying to create an image to use as a test pattern for a new colormap I'm creating. The map is supposed to have nine unique colors with breaks at the integers from 0-8. The colormap itself is fine, but I can't seem to generate the image itsel.
I'm using pandas to make the test array like this:
mask=pan.DataFrame(index=np.arange(0,100),columns=np.arange(1,91))
mask.ix[:,1:10]=0.0
mask.ix[:,11:20]=1.0
mask.ix[:,21:30]=2.0
mask.ix[:,31:40]=3.0
mask.ix[:,41:50]=4.0
mask.ix[:,51:60]=5.0
mask.ix[:,61:70]=6.0
mask.ix[:,71:80]=7.0
mask.ix[:,81:90]=8.0
Maybe not the most elegant method, but it creates the array I want.
However, when I try to plot it using either imshow or pcolor I get an error. So:
fig=plt.figure()
ax=fig.add_subplot(111)
image=ax.imshow(mask)
fig.canvas.draw()
yields the error: "TypeError: Image data can not convert to float"
and substituting pcolor for imshow yields this error: "AttributeError: 'float' object has no attribute 'view'"
However, when I replace he values in mask with anything else - say random numbers - it plots just fine:
mask=pan.DataFrame(values=rand(100,90),index=np.arange(0,100),columns=np.arange(1,91))
fig=plt.figure()
ax=fig.add_subplot(111)
image=ax.imshow(mask)
fig.canvas.draw()
yields the standard colored speckle one would expect (no errors).
The problem here is that your dataframe is full of objects, not numbers. You can see it if you do mask.dtypes. If you want to use pandas dataframes, create mask by specifying the data type:
mask=pan.DataFrame(index=np.arange(0,100),columns=np.arange(1,91), dtype='float')
otherwise pandas cannot know which data type you want. After that change your code should work.
However, if you want to just test the color maps with integers, then you might be better off using simple numpy arrays:
mask = np.empty((100,90), dtype='int')
mask[:, :10] = 0
mask[:, 10:20] = 1
...
And, of course, there are shorter ways to do that filling, as well. For example:
mask[:] = np.arange(90)[None,:] / 10

Histogram Equalization of matplotlib color tables

I'm new to python and matplotlib and I was wondering whether anyone knew if there were any utilities available to do the equavalent of histogram equalization but to a matplotlib color table? There is a function called matplotlib.colors.Normalize which, if given a image array, will automatically set the bottom and top levels but I want something more intelligent that this. I could always just apply histogram equalization to the data itself but I would rather not touch the data. Any thoughts?
You have to create your own image-specific colormap, but it's not too tricky:
import pylab
import matplotlib.colors
import numpy
im = pylab.imread('lena.png').sum(axis=2) # make grayscale
pylab.imshow(im, cmap=pylab.cm.gray)
pylab.title('orig')
imvals = numpy.sort(im.flatten())
lo = imvals[0]
hi = imvals[-1]
steps = (imvals[::len(imvals)/256] - lo) / (hi - lo)
num_steps = float(len(steps))
interps = [(s, idx/num_steps, idx/num_steps) for idx, s in enumerate(steps)]
interps.append((1, 1, 1))
cdict = {'red' : interps,
'green' : interps,
'blue' : interps}
histeq_cmap = matplotlib.colors.LinearSegmentedColormap('HistEq', cdict)
pylab.figure()
pylab.imshow(im, cmap=histeq_cmap)
pylab.title('histeq')
pylab.show()
Histogram equalization can be applied by modifying the palette (or LUT) of your image, so it would the definition of a palette that is equalized.
I searched a bit and couldn't find source code for computing an equalized palette, so unless something exitss you would have to code it yourself.
You should be started with the description of the algorithm on the Wikipedia article.
You could also ask for help on the matplotlib lists.

Categories

Resources