matplotlib discrete bin plot - python

With discrete bin plot I refer to a type of plot which does not connect the points with a straight line, but uses a constant value for all the region which is closest to each point.
This is an example of this type of plot using PDL and PGPLOT.
pdl> use PDL::Graphics::PGPLOT;dev('/xs');$x=rint(grandom(20)*10);print $x;bin($x);hold;points($x,{color=>'red'})
[-19 -3 4 7 -8 -2 9 15 4 7 1 -14 -4 -4 11 6 -15 -13 2 1]Graphics on HOLD
This type of plot is sometimes useful.
I am interested in knowing a way to display this type of plot in matplotlib. I could not find a specific function.
Alternative ways to do it in matplotlib would also be useful as well as perhaps other packages for plotting in python. Thank you very much!

This is called a step plot in matplotlib:
import matplotlib.pyplot as plt
y = [-19, -3, 4, 7, -8, -2, 9, 15, 4, 7, 1, -14, -4, -4, 11, 6, -15, -13, 2, 1]
plt.step(range(len(y)), y, 'o-', where='mid')

Related

Is there a way to generate Square-Like Wave using Time Series data in Matplotlib?

I am relatively new to Python and Matplotlib. Is there a way generate a "square-like" wave using a Panda series (i.e., a Time Series)?
For example, the following values are in the series:
12, 34, 97, -4, -100, -9, 31, 87, -5, -2, 33, 13, 1
Obviously, if I plot this series, it's not going to appear as a square wave.
Is there a way to tell Python that if the value is greater than zero, then plot consistent horizontal line above zero (e.g., let's say plot the line at 1), and if the value is below zero, plot a horizontal line below zero (e.g., at -1)?
Since this is a time series, I don't expect for it to be a perfect square.
Use np.clip as:
x=[12, 34, 97, -4, -100, -9, 31, 87, -5, -2, 33, 13, 1]
np.clip(x, a_min=-1, a_max=1)
array([ 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1])
Or Series.clip :
s = pd.Series(x)
s = s.clip(lower=-1, upper=1)
If it has values between >=-1 to <=1 then use np.where:
x = np.where(np.array(x)>0, 1, -1) # for series s = np.where(s>0, 1, -1)
print(s)
0 1
1 1
2 1
3 -1
4 -1
5 -1
6 1
7 1
8 -1
9 -1
10 1
11 1
12 1
dtype: int64

How to draw a map using python

I want to draw a map using python, not really a map with full information, just a get together of a series of small shapes to reflect land use.
The data is like below
1 2 2 3 3 2
2 3 3 1 1 2
1 1 1 1 3 3
3 3 3 3 4 1
Each number represents one land use type. and their positions in the matrix are their coordinates.
I used VBA to do that before, the whole map consists many small square shapes representing land use, but since the data was so large, it took a long time to generate the map, also delete the map.
My question are :
I wonder in python, is there any more fast way to generate this kind of map, as a whole, not a series of shapes, i think that would be faster??
I have tried using contourf, as below, but it says "out of bounds for axis 1", but actually, I printed X,Y and cordi, they have the same shape, why still out of bounds?
y = np.arange(0, 4 , 1)
x = np.arange(0, 6 , 1)
X,Y = np.meshgrid(x,y)
# cordi is the matrix containing all the data
# pyplot is imported before
plt.contourf(X,Y, Cordi[X,Y], 8, alpha=.75, cmap='jet')
Thank you very much for answering!
What about using imshow, which produces something like a heatmap. Here is an example:
In [1]: import numpy as np
In [2]: import matplotlib.pyplot as plt
In [3]: coord_data = np.array([[1, 2, 2, 3, 3, 2], [2, 3, 3, 1, 1, 2],
[1, 1, 1, 1, 3, 3], [3, 3, 3, 3, 4, 1]])
In [4]: map = plt.imshow(coord_data)
In [5]: plt.colorbar(map)
Out[5]: <matplotlib.colorbar.Colorbar instance at 0x7f3df2559c20>
In [6]: plt.show()
You can specify the interpolation level using the interpolation keyword (examples), and the colors used using the cmap keyword (example colormaps).
If you don't use interpolation='nearest', neighboring data points with the same value will look like contours.

Matplotlib skips data -

I am trying to plot a bar chart using matplotlib. My issue is I have some "0" values in the list and matplotlib eats some of these values, how do I make sure it always plots all the values.
Here is the code:
counter_trim = counter[6:(len(counter)-6)]
pos = np.arange(len(Test_names[6:]))
width =.65
ax = plt.axes()
ax.set_ylabel('Number of failures')
ax.set_title('Distribution of ABT failures')
ax.set_xticks(pos + (width/2))
xtickNames= ax.set_xticklabels(Test_names[6:])
plt.setp(xtickNames, rotation=90, fontsize=10)
plt.bar(pos, counter_trim, width, color='b')
plt.tight_layout()
print 'Distribution plot can be found here:' +image_filepath
plt.savefig(image_filepath)
To make things more clear,
here are the values of pos : [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
and values of counter_trim: [0, 0, 0, 1, 17, 6, 0, 14, 32, 11, 0, 0, 2, 0, 1, 0, 0]
The code above skips first 3 and last 2 zeros, but rest everything is same!
Any ideas how to avoid this?
try out something like this:
plt.xlim(0, len(counter_trim))
as he is drawing no actual bar I guess the plot command omits these entries. I could not try it with your labels on x as they are not with the text but this worked with a standard axis.

2d numpy.power for polynomial expansion

I am trying to write a function that maps 2d-ndarray to 2d-ndarray. The rows of the input array can be processed independently and there shall be a 1-to-1 correspondence between rows of the input and rows of the output. For each row of the input, the polynomial expansion of a given order for the row shall be computed (see docstring for an example). The current implementation works; however it requires an explicit loop over the rows and duplication of rows in the "powerMatrix"). Is it possible to get the same result with a single call to numpy.power? Btw.: the order of the entries in the result's rows doesn't matter to me.
import numpy
def polynomialFeatures(x, order):
""" Generate polynomial features of given order for data x.
For each row of ndarray x, the polynomial expansions are computed, i.e
for row [x1, x2] and order 2, the following row of the result matrix is
computed: [1, x1, x1**2, x2, x1*x2, x1**2*x2, x2**2, x1*x2**2, x1**2*x2**2]
Parameters
----------
x : array-like
2-D array; for each of its rows, the polynomial features are created
order : int
The order of the polynomial features
Returns
-------
out : ndarray
2-D array of shape (x.shape[0], (order+1)**x.shape[1]) containing the
polynomial features computed for the rows of the array x
Examples
--------
>>> polynomialFeatures([[1, 2, 3], [-1, -2, -3]], 2)
array([[ 1 3 9 2 6 18 4 12 36 1 3 9 2 6 18 4 12
36 1 3 9 2 6 18 4 12 36]
[ 1 -3 9 -2 6 -18 4 -12 36 -1 3 -9 2 -6 18 -4 12
-36 1 -3 9 -2 6 -18 4 -12 36]])
"""
x = numpy.asarray(x)
# TODO: Avoid duplication of rows
powerMatrix = numpy.array([range(order+1)] * x.shape[1]).T
# TODO: Avoid explicit loop, and use numpy's broadcasting
F = []
for i in range(x.shape[0]):
X = numpy.power(x[i], powerMatrix).T
F.append(numpy.multiply.reduce(cartesian(X), axis=1))
return numpy.array(F)
print numpy.all(polynomialFeatures([[1, 2, 3], [-1, -2, -3]], 2) ==
numpy.array([[1, 3, 9, 2, 6, 18, 4, 12, 36, 1,
3, 9, 2, 6, 18, 4, 12, 36, 1, 3,
9, 2, 6, 18, 4, 12, 36],
[1, -3, 9, -2, 6, -18, 4, -12, 36, -1,
3, -9, 2, -6, 18, -4, 12, -36, 1, -3,
9, -2, 6, -18, 4, -12, 36]]))
Thanks,
Jan
EDIT: The missing function cartesian is defined here: Using numpy to build an array of all combinations of two arrays
The basic idea is to move the dimension (in your case, dimension 0, the number of rows) that's irrelevant to the calculation "out of the way" into a higher dimension and then automatically broadcast over it.
I'm not sure what your cartesian method is doing, but here's a solution that uses np.indices to generate indexing tuples over the X matrix:
import numpy as np
def polynomial_features(x, order):
x = np.asarray(x).T[np.newaxis]
n = x.shape[1]
power_matrix = np.tile(np.arange(order + 1), (n, 1)).T[..., np.newaxis]
X = np.power(x, power_matrix)
I = np.indices((order + 1, ) * n).reshape((n, (order + 1) ** n)).T
F = np.product(np.diagonal(X[I], 0, 1, 2), axis=2)
return F.T

Matplotlib many subplots xtick labels intercepting

I'm plotting many subplots in the same figure. I encounter the problem that xtick labels intercept one with each other. I do not want any space between the subplots.
Here is an example:
In particular I would like xtick labels not to be above/below the green lines, just like it happens at the points indicated with red squares.
One idea I had so far was, in a case where my max=4 and min=0, I'd draw tick labels for 1 2 and 3 at their respective locations, e.g 1,2,3. Then I'd draw 4 at the position 3.8 and 0 at the position 0.2. Any ideas?
thanks!
Not exactly what you asked for, but a quick solution is to set the alignment parameter:
pylab.xticks(..., horizontalalignment='left')
pylab.yticks(..., verticalalignment='bottom')
This will apply to all ticks.
This is how I would do it:
axScatter.set_xticks([0, 1, 2, 3, 4 ,5 ,6])
axScatter.set_yticks([-8, -6, -4, -2, 0, 2, 4, 6])
And you can use:
axScatter.yaxis.set_major_formatter(nullfmt)
To make the y axis labels disappear for the top right and bottom right plots.
The whole plt.figure routine should look something like this:
fig = plt.figure()
axplot_topleft = fig.add_subplot(2,2,1)
axplot_topleft.xaxis.set_major_formatter(nullfmt)
axplot_topleft.set_yticks([-8, -6, -4, -2, 0, 2, 4, 6])
axplot_topright = fig.add_subplot(2,2,2)
axplot_topright.xaxis.set_major_formatter(nullfmt)
axplot_topright.yaxis.set_major_formatter(nullfmt)
axplot_bottomleft = fig.add_subplot(2,2,3)
axplot_bottomleft.set_xticks([0, 1, 2, 3, 4 ,5 ,6])
axplot_bottomleft.set_yticks([-8, -6, -4, -2, 0, 2, 4, 6])
axplot_bottomright = fig.add_subplot(2,2,4)
axplot_bottomright.yaxis.set_major_formatter(nullfmt)
axplot_bottomright.set_xticks([0, 1, 2, 3, 4 ,5 ,6])

Categories

Resources