how can i color specific pixels in matplotlib imshow? - numpy

I am plotting a numpy matrix with imshow and nearest neighbor interpolation in blue scale.
How can i color specific pixels in the plot so that they would be, say red?
pyplot.imshow(matrix, interpolation='nearest',cmap = cm.Blues)
pyplot.show()

You can't directly color pixels red with a colormap that doesn't have red in it. You could pick a red-blue colormap and norm your matrix data into the blue part, but you can also just plot over an imshow image:
from matplotlib import pyplot
from numpy.random import random
matrix = random((12,12))
from matplotlib import cm
pyplot.imshow(matrix, interpolation='nearest', cmap=cm.Blues)
pyplot.scatter([6,8], [10,7], color='red', s=40)
pyplot.show()

Related

Warping Matplotlib/Seaborn Scatter Plot into Parallelogram

I have a 2D scatterplot (in either matplotlib or seaborn) and an angle e.g. 64 degrees. I want to plot a warped version of this scatter plot where the x-axis of the first plot is held fixed but the second axis is warped such that the y-axis of the first plot is now at the given angle with the x-axis of the new plot (i.e. 64 degrees). How can I do this?
In other words, I want to take the original scatter plot and "push" the y-axis to the right to form a parallelogram-like plot where the angle between the old y axis and the old/new x-axis is the given angle.
Here is an adaption of an old tutorial example:
import matplotlib.pyplot as plt
from matplotlib.transforms import Affine2D
import mpl_toolkits.axisartist.floating_axes as floating_axes
import numpy as np
fig = plt.figure()
skewed_transform = Affine2D().skew_deg(90 - 64, 0)
grid_helper = floating_axes.GridHelperCurveLinear(skewed_transform, extremes=(-0.5, 1.5, -0.5, 1.5))
skewed_ax = floating_axes.FloatingSubplot(fig, 111, grid_helper=grid_helper)
skewed_ax.set_facecolor('0.95') # light grey background
skewed_ax.axis["top"].set_visible(False)
skewed_ax.axis["right"].set_visible(False)
fig.add_subplot(skewed_ax)
x, y = np.random.rand(2, 100) # random point in a square of [0,1]x[0,1]
skewed_ax.scatter(x, y, transform=skewed_transform + skewed_ax.transData)
plt.show()

plot_surface reduces density of points

Trying to plot a surface using matplotlib. However, the plotted surface has lower grid density than the meshgrid.
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
xgrid = np.arange(0,1,1/100)
ygrid = xgrid.copy()
xx, yy = np.meshgrid(xgrid,ygrid)
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
ax.plot_surface(xx,yy,np.square(xx)+np.square(yy))
The meshgrid was defined to have 100 segments in each direction. However, the surface in the figure doesn't have 100 segments. Is there anyway to render the surface with the same density?
Don't worry, you don't have to count the number of segments, so I overlap the plot with a scatter plot with the same points
ax.scatter3D(xx,yy,np.square(xx)+np.square(yy))
Upon zooming in, you can see that each grid of the surface plot has a scatter point in the middle, which shows that the plot_surface changed the density of the points.
Usually it doesn't matter for smooth plots such as these, but I have singular points in my data which sometimes disappear in the surface plot because of this

Periodic grayscale colormap

To plot an angle, I need an intuitive periodic colormap. I found the 'hsv' colormap (https://matplotlib.org/users/colormaps.html) which is periodic, but very not intuitive because to me green is not further away from blue than from yellow for example.
I think a periodic grayscale colormap is exactly what I need: changing smoothly from black in both edges to white in the middle (or the other way around).
I could not find this colormap in the built-in ones. Does anyone know of such existing colormap or a way to manually define it?
The easiest way to create a the desired black-white-black colormap is to use matplotlib.colors.LinearSegmentedColormap.from_list()
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
colors = ["black", "white", "black"]
cmap=LinearSegmentedColormap.from_list("", colors)
Then use it as any usual colormap:
import numpy as np
r = np.linspace(0,1)
t = np.linspace(0,2*np.pi, 360)
R,T = np.meshgrid(r,t)
fig, ax = plt.subplots(subplot_kw=dict(projection="polar"))
ax.pcolormesh(T,R,T, cmap=cmap)
plt.show()

matplotlib surface plot with hidden zaxis

when I change the viewpoint of plot_surface in matplolib in (90,0), the zaxis is not clear, and it's useless in this plot. I want to generate the image same as matlab as below
matlab surf with view (0,90),with contour lines
I used matplotlib function imshow can generate matrix image, but there are no lines (similar in contourplot lines)in the image. how can i generate the image with plot_surface in python with a viewpoint of (90,0),bu without zaxis?
matplotlib with plot_surface,view(90,0),withou lines and zaxis
You can use contourf from matplotlib:
import matplotlib.pyplot as plt
import numpy as np
X, Y = np.meshgrid(range(100), range(100))
Z = X**2+Y**2
plt.contourf(X, Y, Z, [i for i in np.linspace(Z.min(),Z.max(),30)])
plt.show()
, which results in:

How to scale heatmap color to a uniform color distribution?

I'm plotting a simple heatmap with a skewed distribution of values
import numpy as np
import matplotlib.pyplot as plt
import random
import matplotlib
size=100
data=np.array([[random.expovariate(1) for _ in range(size)] for _ in range(size)])
fig, ax=plt.subplots()
heatmap=ax.pcolormesh(data, cmap=matplotlib.cm.Reds)
fig.colorbar(heatmap)
It would be great, if I could change the color scaling such that values below some threshold are a fixed color (for example lowest color in the cmap) and all other values are scaled to show a more uniform distribution of colors (for example exponential or power rescaling with some parameter).
Is there an easy way to rescale my colormap without changing my data values?
If you are happy with a linear bit of the scale, there is:
heatmap=ax.pcolormesh(data, cmap=matplotlib.cm.Reds, vmin=0, vmin=1)
Now the colors are scaled form 0 to 1.
If you want to have a non-linear colormap, it is possible, as well. In order to get it and the respective color bar correct, you'll need to jump through some hoops.
The accepted answer to nonlinear colormap, matplotlib should give you the recipe.