Python matplotlib: how to let matrixplot have variable column widths - python

I have a simple need but cannot find its simple solution. I have a matrix to plot, but I wish the row/columns to have given widths.
Something looking like a blocked matrix where you tell block sizes.
Any workaround with the same visual result is accepted.
import matplotlib.pyplot as plt
import numpy as np
samplemat = np.random.rand(3,3)
widths = np.array([.7, .2, .1])
# Display matrix
plt.matshow(samplemat)
plt.show()

matshow or imshow work with equal sized cells. They hence cannot be used here. Instead you may use pcolor or pcolormesh. This would require to supply the coordinates of the cell edges.
Hence you first need to calculate those from the given width. Assuming you want them to start at 0, you may just sum them up.
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(43)
samplemat = np.random.rand(3,3)
widths = np.array([.7, .2, .1])
coords = np.cumsum(np.append([0], widths))
X,Y = np.meshgrid(coords,coords)
# Display matrix
plt.pcolormesh(X,Y,samplemat)
plt.show()

Related

How to make a grid equidistance grid from a dataframe

I have a matrix of dataframe 128x128 and I want to make it equidistance for interpolation how can I do it? Here is the grid from that data frame and now there are points that are not the same distance.How can I make this uniformly spaced.
Do you want something like this? You can change the number of points as you want, just change a.
import numpy as np
import matplotlib.pyplot as plt
a = np.linspace(0,3,4)
grid = np.dstack(np.meshgrid(a,a))
plt.scatter(grid[:,:,0],grid[:,:,1])
plt.show()

Retrieving Matplotlib Heatmap Colors

I am trying to retrieve the colors of each cell on a matplotlib heatmap, generated by the imshow() function, such as performed by the magic_function below:
import matplotlib.pyplot as plt
import numpy as np
hm = plt.imshow(np.random.rand(10, 10))
color_matrix = hm.magic_function() #returns matrix containing the RGB/Hex values of each cell
You are looking for the colormap that is used by the image created via imshow. Now of course you can reverse engineer how that colormap got into the image in the first place like the other answer suggests. That seems cumbersome and often enough isn't even possible.
So given an AxesImage (the object returned by imshow) or for that matter any other ScalarMappable, you get the colormap in use via .cmap. Since the data values are normalized to the range between 0..1, you need a normalization, which you get from the .norm attribute. Finally, you need the data, which you get from the .get_array() method.
The magic_function is hence a chain of three functions.
im = plt.imshow(np.random.rand(10, 10))
color_matrix = im.cmap(im.norm(im.get_array()))
color_matrix is now the (10, 10, 4)-shaped RGBA array of colors corresponding to the pixels in the image.
Building upon this answer, you need to understand the default color map chosen by matplotlib since you didn't provide one. The documentation states that it is the value of plt.rcParams["image.cmap"], so we use that.
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.cm as cm
from matplotlib.colors import Normalize
data = np.random.rand(10, 10)
cmap = cm.get_cmap(plt.rcParams["image.cmap"])
hm = plt.imshow(data)
norm = Normalize(vmin=data.min(), vmax=data.max())
rgba_values = cmap(norm(data))
The RGBA value of the upper left cell would then be rgba_values[0,0]

matplotlib turn an array into a parametric plot

Suppose I have the following script:
import numpy as np
import matplotlib.pyplot as plt
A = np.array([[1,1,1,0],[0,0,1,0],[0,1,0,0],[0,0,0,0]])
How can I plot just the values of A that are equal to 1, leaving the 0's blank? Basically I'm looking to plot just those points, and not as a pcolormesh or something similar.
If you change the values to non-integer values they will not appear in your array.
x(x == -1) = NaN;
plot(x)

Custom scale from simple list or dict?

I need to make a custom scale for an axis. Before diving into http://matplotlib.org/examples/api/custom_scale_example.html, I'm wondering if there is an easier way for my special case.
A picture is worth a thousand words, so here we go:
See the value in each row next to the filename ? I would like the row height to be relative to the difference between it and the previous one. I'd start from 0 and would have to define a top limit so I see the last row.
Try matplotlib's pcolormesh with which you can create irregularly shaped grids.
from matplotlib import pyplot as plt
import numpy as np
y1D = np.hstack([0, np.random.random(9)])
y1D = np.sort(y1D)/np.max(y1D)
x, y = np.meshgrid(np.arange(0,1.1,0.1),y1D)
plt.pcolormesh(x,y, np.random.random((10,10)))
plt.show()
You can use this recipe and adapt to your needs:
import numpy as np
import matplotlib.pyplot as plt
grid = np.zeros((20,20))
for i in range(grid.shape[0]):
r = np.random.randint(1,19)
grid[i,:r] = np.random.randint(10,30,size=(r,))
plt.imshow(grid,origin='lower',cmap='Reds',interpolation='nearest')
plt.yticks(list(range(20)),['File '+str(i) for i in range(20)])
plt.colorbar()
plt.show()
, the result is this:

Plotting random point on Function - Pandas

I want to graph a function 2D or 3D
for example a f(x) = sin(x)
Then randomly plot a certain amount of points
I am using IPython and I think this might be possible using Pandas
You can use np.random.uniform to generate a few random points along x-axis and calculate corresponding f(x) values.
import numpy as np
import matplotlib.pyplot as plt
# generate 20 points from uniform (-3,3)
x = np.random.uniform(-3, 3, size=20)
y = np.sin(x)
fig, ax = plt.subplots()
ax.scatter(x,y)
You should post example code so people can demonstrate it more easily.
(numpy.random.random(10)*x_scale)**2
Generate an array of random numbers between 0 and 1, scale as appropriate (so for (-10,0);
10*numpy.random.random(100) -10
then pass this to any function that can calculate the value of f(x) for each element of the array.
Use shape() if you need to play around with layout of the array.
If you want to use Pandas...
import pandas as pd
import matplotlib.pyplot as plt
x=linspace(0,8)
y=sin(x)
DF=pd.DataFrame({'x':x,'y':y})
plot values:
DF.plot(x='x',y='y')
make a random index:
RandIndex=randint(0,len(DF),size=20)
use it to select from original DF and plot:
DF.iloc[RandIndex].plot(x='x',y='y',kind='scatter',s=120,ax=plt.gca())

Categories