When I plot an empty 2D histogram I get an unexpected point in the middle of the plot and am not sure why
max = 100
x = np.zeros(10000)
y = np.zeros(10000)
heatmap, xAxis, yAxis = np.histogram2d(x, y, bins=max)
fig, (ax1, ax2) = plt.subplots(1, 2)
ax1.imshow(heatmap, interpolation='none')
ax2.imshow(convolve(heatmap, Gaussian2DKernel(x_stddev=sigma)), interpolation='none')
plt.show()
Resulting plot
Matplotlib plot is correct. Your data is all 0's
x = np.zeros(10000)
y = np.zeros(10000)
so your histogram will have only one point, (0, 0) with a strictly positive value, 1. All other points will be 0.
This is exactly what you have on your left-hand side plot!
To set correct values on the axis, please follow the snippet below:
import matplotlib.pyplot as plt
import numpy as np
max_ = 100
x = np.zeros(10000)
y = np.zeros(10000)
heatmap, xAxis, yAxis = np.histogram2d(x, y, bins=max_)
fig, (ax1, ax2) = plt.subplots(1, 2)
ax1.axis([min(xAxis), max(xAxis), min(yAxis), max(yAxis)])
ax1.set_aspect(1)
ax1.pcolormesh(xAxis, yAxis, heatmap)
plt.show()
Related
I am trying to get a continuous color scale in matplotlib for a log plot. But I also want to preserve the nice tick structure and upper and lower limits in the colorbar.
I can only figure out how to do one or the other.
Here the code that generates the two versions
import matplotlib.ticker as ticker
import numpy as np
x = np.linspace(1,200, 50)
y = np.linspace(1,300, 50)
z = np.outer(y, x)
bounds = [np.amin(z), np.amax(z)]
bounds = np.log10(bounds)
bounds[0] = np.floor(bounds[0])
bounds[1] = np.ceil(bounds[1])
bounds = np.power(10, bounds)
fig, ax = plt.subplots()
tickLocator = ticker.LogLocator()
CS = ax.contourf(x, y, z, locator=tickLocator)
ax.set_title("Not enough color bar levels")
cbar = plt.colorbar(CS)
fig, ax = plt.subplots()
tickLocator = ticker.LogLocator(subs=range(1, 10))
CS = ax.contourf(x, y, z, locator=tickLocator)
ax.set_title("Labels missing and not enough range in color bar")
cbar = plt.colorbar(CS)
print("Boundary values")
print(bounds)
print("Tick values")
print(cbar.get_ticks())
plt.show()
With the first version I get nice end points for the ticks, but the levels are very coarse.
With the second version most of the tick labels are missing and the highest tick is smaller than the biggest value in the array.
I found something that works for me by using pcolormesh instead of contourf.
Here the code and output for anyone with a similar problem
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import numpy as np
x = np.linspace(1,200, 200)
y = np.linspace(1,300, 200)
z = np.outer(y, x)
bounds = [np.amin(z), np.amax(z)]
bounds = np.log10(bounds)
bounds[0] = np.floor(bounds[0])
bounds[1] = np.ceil(bounds[1])
bounds = np.power(10, bounds)
fig, ax = plt.subplots()
CS = ax.pcolormesh(x, y, z, norm=colors.LogNorm(*bounds), shading="auto")
cbar = plt.colorbar(CS, ax=ax)
print("Boundary values")
print(bounds)
print("Tick values")
print(cbar.get_ticks())
plt.show()
I want to show only exact values (x, y) on axes or coordinates of data point by matplotlib. My work below that
def plot_sample_individual(id = None):
if id is None:
id = random.randint(0, len(ca_the))
fig, ax = plt.subplots(1, 1, figsize=(5, 5))
ax.plot(week[:7], ca_the[id, :],'--ro')
ax.set_title('ID cá thể '+ str(ID[id, 0]))
ax.set_ylabel('Sản lượng trứng trung bình tuần')
ax.set_xlabel('Tuần')
and result of code is:
How to show only 3 values on axes y and 5 values in axes x ?
Use the x and y data to set the Axes ticks:
from matplotlib import pyplot as plt
x = [24,25,26,27,28]
y = [7,4,5,4,4]
fig,ax = plt.subplots()
ax.plot(x,y)
ax.set_xticks(x)
ax.set_yticks(y)
plt.show()
plt.close()
Ticks and tick labels
I want to plot with the same x and y axis values (in a separate subplot) the errorbar that I display in the following way (the errorbar is correlated to the histogram drawn under):
import matplotlib.pyplot as plt
fig, ax1 = plt.subplots()
n, bin_edges, patches = ax1.hist(x, log=True, bins='doane', color='red')
bin_centres = (bin_edges[:-1] + bin_edges[1:]) / 2.
ax1.errorbar(bin_centres, n, fmt='o')
plt.xlabel("X_label")
plt.ylabel("Y_label")
plt.show()
Is there a way of specifying the position of axis labels?
labelpad sets the space between tick labels and the axis label.
Since the width of tick labels is unknown it appears to thus be impossible to precisely position axis labels.
Here is a MWE where I would like to have the ylabels of both subplots to be vertically aligned:
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
np.random.seed(19680801)
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
fig, axs = plt.subplots(2,1)
for ax in axs:
n, bins, patches = ax.hist(x, 50, normed=1, facecolor='g', alpha=0.75)
ax.set_ylabel('Probability $y$')
ax.grid(True)
ax.set_yticklabels([ r'\$\num{{{:g}}}\$'.format(item) for item in ax.get_yticks().tolist() ])
fig.show()
I tried this, but it does not work:
fig.canvas.draw()
ylabelposition = ax.yaxis.label.get_position()
ax.set_yticklabels([ r'\$\num{{{:g}}}\$'.format(item) for item in ax.get_yticks().tolist() ])
ax.yaxis.label.set_position(ylabelposition)
In the reference, they are described as:
axis('equal')
changes limits of x or y axis so that equal increments of x and y have the same length; a circle is
circular.:
axis('scaled')
achieves the same result by changing the dimensions of the plot box instead of the axis data limits.:
But I did not understand the part 'by changing the dimensions of the plot box'.
So I compared directly
import numpy as np
import matplotlib.pyplot as plt
plt.close('all')
x = np.array(np.linspace(-np.pi, np.pi))
y = np.sin(x)
ax1 = plt.subplot(2, 1, 1)
ax1 = plt.plot(x, y)
plt.axis('scaled')
ax1 = plt.subplot(2, 1, 2)
plt.plot(x, y)
plt.axis('equal')
There is only a slight difference that the width is shorter when plotted with plt.axis('scaled').
How can I know the difference better?
I think the difference becomes more apparent, if you use different data.
import numpy as np
import matplotlib.pyplot as plt
x = np.array(np.linspace(-np.pi, np.pi))
y = np.sin(x)*np.pi
ax1 = plt.subplot(2, 1, 1)
ax1 = plt.plot(x, y)
plt.axis('scaled')
ax1 = plt.subplot(2, 1, 2)
plt.plot(x, y)
plt.axis('equal')
plt.show()
So the difference is if the axes around the plot are changed according to the aspect, or if they stay the same as in a usual subplot and are scaled such, that the aspect of the plot data is equal.