matplotlib polar 2d histogram - matplotlib

I am trying to plot some histogrammed data on a polar axis but it wont seem to work properly. An example is below, I use the custom projection found How to make the angles in a matplotlib polar plot go clockwise with 0° at the top? it works for a scatter plot so I think my problem is with the histogram function. This has been driving me nuts all day, does anyone know what I am doing wrong...........
import random
import numpy as np
import matplotlib.pyplot as plt
baz = np.zeros((20))
freq = np.zeros((20))
pwr = np.zeros((20))
for x in range(20):
baz[x] = random.randint(20,25)*10
freq[x] = random.randint(1,10)*10
pwr[x] = random.randint(-10,-1)*10
baz = baz*np.pi/180.
abins = np.linspace(0,2*np.pi,360) # 0 to 360 in steps of 360/N.
sbins = np.linspace(1, 100)
H, xedges, yedges = np.histogram2d(baz, freq, bins=(abins,sbins), weights=pwr)
plt.figure(figsize=(14,14))
plt.subplot(1, 1, 1, projection='northpolar')
#plt.scatter(baz, freq)
plt.pcolormesh(H)
plt.show()

Your code works if you explicitly pass a mgrid (with similar characteristics than your a bins and sbins) to the pcolormesh command.
Below is an example inspired by your code:
import matplotlib.pyplot as plt
import numpy as np
#Generate the data
size = 200
baz = 10*np.random.randint(20, 25, size)*np.pi/180.
freq = 10*np.random.randint(1, 10, size)
pwr = 10*np.random.randint(-10, -1, size)
abins = np.linspace(0, 2*np.pi, 360) # 0 to 360 in steps of 360/N.
sbins = np.linspace(1, 100, 50)
H, xedges, yedges = np.histogram2d(baz, freq, bins=(abins,sbins), weights=pwr)
#Grid to plot your data on using pcolormesh
theta, r = np.mgrid[0:2*np.pi:360j, 1:100:50j]
fig, ax = plt.subplots(figsize=(14,14), subplot_kw=dict(projection='northpolar'))
ax.pcolormesh(theta, r, H)
ax.set_yticklabels([]) #remove yticklabels
plt.show()

Related

multi animation whit subplot

I got some sort of a problem with a pendulum animation, I tried to display my animation (the pendulum's movement) next to a graph in two separate axes, but when I try my code, it barely works displaying two axes that overlap on one another... Here is what I tried:
PS: best would be that the circles I was intended to add at the end of my pendulum appear on the final animation, but I really have no idea how to put them only on a particular ax
from numpy import sin, cos, pi, array
import numpy as np
import scipy.integrate
import matplotlib.pyplot as plt
import matplotlib.animation as animation
g = 10
y0 = np.array([np.pi / 2.0, 0]) # angle, vitesse
j = 0.2
def f(y, t):
return np.array([y[1], -g * np.sin(y[0])-j*y[1]])
t = np.linspace(0, 100, 10000)
y = scipy.integrate.odeint(f, y0, t)
theta, thetadot = y[:, 0], y[:, 1]
fig, axs = plt.subplots(1,2)
axs[0] = fig.add_subplot(xlim=(-1.5, 1.5), ylim=(-1.5, 1.5))
axs[0].grid()
axs[0].set_box_aspect(1)
# anchor = plt.Circle((0, 0), 0.01, color='black')
# mass = plt.Circle((sin(y0[0]),-cos(y0[0])), 0.2, color='black')
pendulums = axs[0].plot((0, sin(y0[0])), (0, -cos(y0[0])), 'o-', color = 'black')
# plt.gca().add_patch(weight) # adding circles
# plt.gca().add_patch(attach)
phase = axs[1].plot(theta,thetadot)
def animate(i):
angle = theta[i]
x = (0, sin(angle))
y = (0, -cos(angle))
#mass.center = (x[1],y[1])
pendulums[0].set_data(x, y)
anim = animation.FuncAnimation(fig, animate, interval=10)
plt.show()

Generate heat map from 2D data

I have a set of X,Y data points(from Remote sensing image),and I drew a scatter plot through the tutorial, the link is as follows:Generate a heatmap in MatPlotLib using a scatter data set
But when I try to draw a heat map, an error occurs:Heatmap cannot be displayed.
Is there a way to display two-dimensional data in a heat map, the different colors in the heat map represent the density of the pixels?
This is my code and result:
import rasterio
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from scipy.ndimage.filters import gaussian_filter
def myplot(x, y, s, bins=1000):
heatmap, xedges, yedges = np.histogram2d(x, y, bins=bins)
heatmap = gaussian_filter(heatmap, sigma=s)
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
return heatmap.T, extent
fig, axs = plt.subplots(1, 2)
dataset = rasterio.open('E:/Jupyter Notebook/LC81490312016259LGN00/LC8_subset_layerstacking.tif')
red_band = dataset.read(4)
NIR_band = dataset.read(5)
np.seterr(divide='ignore', invalid='ignore')
ndvi = (NIR_band.astype(float)-red_band.astype(float))/(NIR_band.astype(float)+red_band.astype(float))
ndvi_flat = np.ndarray.flatten(ndvi)
red_band_flat = np.ndarray.flatten(red_band)
x = ndvi_flat
y = red_band_flat
sigmas = [0, 16]
for ax, s in zip(axs.flatten(), sigmas):
if s == 0:
ax.plot(x, y, 'k.', markersize=0.1)
#ax.set_aspect('equal')
ax.set_title("Scatter plot")
ax.set_xlabel('NDVI')
ax.set_ylabel('Red Reflectance')
else:
img, extent = myplot(x, y, s)
ax.imshow(img, origin='lower',cmap=cm.jet)
ax.set_title("Smoothing with $\sigma$ = %d" % s)
ax.set_xlabel('NDVI')
ax.set_ylabel('Red Reflectance')
plt.show()
The left image is a black scatter plot (no pixel density information), and the right image is a heat map
The code and the data I need to process are stored in GitHub:https://github.com/Flyinfish-gzh/remote-sensing-data-visualization

Python Subplot 3d Surface and Heat Map

I plan to create a figure in matplotlib, with a 3D surface on the left and its corresponding contour map on the right.
I used subplots but it only show the contour map (with blank space for the surface), and a separate figure for the surface.
Is it possible to create these plots in one figure side-by side?
EDIT: The code is as follows:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
import numpy as np
x = np.arange(-5, 5, 0.25)
y = np.arange(-5, 5, 0.25)
x, y = np.meshgrid(x, y)
r = np.sqrt(x**2 + y**2)
z = np.sin(r)
fig, (surf, cmap) = plt.subplots(1, 2)
fig = plt.figure()
surf = fig.gca(projection='3d')
surf.plot_surface(x,y,z)
cmap.contourf(x,y,z,25)
plt.show()
I guess it's hard to use plt.subplots() in order to create a grid of plots with different projections.
So the most straight forward solution is to create each subplot individually with plt.subplot.
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
import numpy as np
x = np.arange(-5, 5, 0.25)
y = np.arange(-5, 5, 0.25)
x, y = np.meshgrid(x, y)
r = np.sqrt(x**2 + y**2)
z = np.sin(r)
ax = plt.subplot(121, projection='3d')
ax.plot_surface(x,y,z)
ax2 = plt.subplot(122)
ax2.contourf(x,y,z,25)
plt.show()
Of course one may also use the gridspec capabilities for more sophisticated grid structures.

group boxplot histogramming

I would like to group my data and to plot the boxplot for all the groups. There are many questions and answer about that, my problem is that I want to group by a continuos variable, so I want to histogramming my data.
Here what I have done. My data:
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
x = np.random.chisquare(5, size=100000)
y = np.random.normal(size=100000) / (0.05 * x + 0.1) + 2 * x
f, ax = plt.subplots()
ax.plot(x, y, '.', alpha=0.05)
plt.show()
I want to study the behaviour of y (location, width, ...) as a function of x. I am not interested in the distribution of x so I will normalized it.
f, ax = plt.subplots()
xbins = np.linspace(0, 25, 50)
ybins = np.linspace(-20, 50, 50)
H, xedges, yedges = np.histogram2d(y, x, bins=(ybins, xbins))
norm = np.sum(H, axis = 0)
H /= norm
ax.pcolor(xbins, ybins, np.nan_to_num(H), vmax=.4)
plt.show()
I can plot histogram, but I want boxplot
binning = np.concatenate(([0], np.sort(np.random.random(20) * 25), [25]))
idx = np.digitize(x, binning)
data_to_plot = [y[idx == i] for i in xrange(len(binning))]
f, ax = plt.subplots()
midpoints = 0.5 * (binning[1:] + binning[:-1])
widths = 0.9 * (binning[1:] - binning[:-1])
from matplotlib.ticker import MultipleLocator, FormatStrFormatter
majorLocator = MultipleLocator(2)
ax.boxplot(data_to_plot, positions = midpoints, widths=widths)
ax.set_xlim(0, 25)
ax.xaxis.set_major_locator(majorLocator)
ax.set_xlabel('x')
ax.set_ylabel('median(y)')
plt.show()
Is there an automatic way to do that, like ax.magic(x, y, binning)? Is there a better way to do that? (Have a look to https://root.cern.ch/root/html/TProfile.html for example, which plot the mean and the error of the mean as error bars)
In addition, I want to minize the memory footprint (my real data are much more than 100000), I am worried about data_to_plot, is it a copy?

matplotlib: imshow a 2d array with plots of its marginal densities

How can one plot a 2d density with its marginal densities,
along the lines of
scatterplot-with-marginal-histograms-in-ggplot2
or
2D plot with histograms / marginals,
in matplotlib ?
In outline,
# I have --
A = a 2d numpy array >= 0
xdens ~ A.mean(axis=0)
ydens ~ A.mean(axis=1)
# I want --
pl.imshow( A )
pl.plot( xdens ) narrow, below A
pl.plot( ydens ) narrow, left of A, with the x y axes flipped
Added in 2017: see the lovely example of seaborn.jointplot,
also this on SO. (The question was in 2013, before seaborn.)
You can use sharex and sharey with subplots:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec
t = np.linspace(0, 31.3, 100)
f = np.linspace(0, 1000, 1000)
a = np.exp(-np.abs(f-200)/200)[:, None] * np.random.rand(t.size)
flim = (f.min(), f.max())
tlim = (t.min(), t.max())
gs = gridspec.GridSpec(2, 2, width_ratios=[1,3], height_ratios=[3,1])
ax = plt.subplot(gs[0,1])
axl = plt.subplot(gs[0,0], sharey=ax)
axb = plt.subplot(gs[1,1], sharex=ax)
ax.imshow(a, origin='lower', extent=tlim+flim, aspect='auto')
plt.xlim(tlim)
axl.plot(a.mean(1), f)
axb.plot(t, a.mean(0))
Which gives you: