Reputation: 189
I am trying to create a density plot with a given data and using log scales in the two axes x,y, using the version of Matplotlib 2.0.0. I have made the following code, the problem is that for the log plot case don't give the correct functional behaviour.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
init = 0.0
points = 500
final_value = 100
steep = (final_value-init)/points
list_values_x = np.arange(init,final_value,steep)
list_values_y = np.arange(init,final_value,steep)
#WE CREATE OUT DATA FILE
f1 = open("data.txt", "w")
for i in list_values_x:
for j in list_values_y:
f1.write( str(i) +" "+str(j)+" "+str(0.0001*(i**2+j**2)) +"\n")
f1.close()
#NOW WE OPEN THE FILE WITH THE DATA AND MAKE THE PLOT
x,y,temp = np.loadtxt('data.txt').T #Transposed for easier unpacking
nrows, ncols = points, points
grid = temp.reshape((nrows, ncols))
# LINEAR PLOT
fig1 = plt.imshow(grid, extent=(x.min(), x.max(), y.max(), y.min()),
interpolation='nearest', cmap=cm.gist_rainbow)
plt.axis([x.min(), x.max(),y.min(), y.max()])
plt.colorbar()
plt.suptitle('Example', fontsize=15)
plt.xlabel('x', fontsize=16)
plt.ylabel('y', fontsize=16)
plt.show()
# LOG-LOG PLOT
fig, (ax1) = plt.subplots(ncols=1, figsize=(8, 4))
ax1.imshow(grid, aspect="auto", extent=(1, 1e2, 1, 1e2), interpolation='nearest')
ax1.set_yscale('log')
ax1.set_xscale('log')
ax1.set_title('Example with log scale')
plt.show()
The data that I am using in order to make the plot is irrelevant, it's just an example. So that, the first plot is given with a linear scale. The second plot is given with a log-log scale, but is clear that it's incorrect, the behaviour beetwen the two plots is absolutely different and I am using the same data. Moreover, I don't know how put a colorbar in the log-log plot
Any idea why this happens? Thanks for your attention.
PD: In order to build the log-log plot, I have used part of the code that apears in "Non-linear scales on image plots" given in (http://matplotlib.org/devdocs/users/whats_new.html#non-linear-scales-on-image-plots)
Upvotes: 1
Views: 1298
Reputation: 339170
Using the extent keyword and it with extent=(xmin, xmax, ymin, ymax)
makes more sense when additionally using origin="lower"
in imshow
. You might also want to set the limits for the axes, since the automatic feature does not work too well for log scales.
Here is the complete example:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from mpl_toolkits.axes_grid1 import make_axes_locatable
points = 500
init = 0.0
final_value = 100
steep = (final_value-init)/points
x = np.arange(init,final_value,steep)
y = np.arange(init,final_value,steep)
X,Y = np.meshgrid(x,y)
Z = 0.0001*(X**2+Y**2)
fig, (ax, ax1) = plt.subplots(ncols=2, figsize=(8, 4))
# LINEAR PLOT
im = ax.imshow(Z, extent=(x.min(), x.max(), y.min(), y.max() ),
interpolation='nearest', cmap=cm.gist_rainbow, origin="lower")
ax.set_title('lin scale')
#make colorbar
divider = make_axes_locatable(ax)
ax_cb = divider.new_horizontal(size="5%", pad=0.05)
fig.add_axes(ax_cb)
fig.colorbar(im, cax = ax_cb, ax=ax)
# LOG-LOG PLOT
im1 = ax1.imshow(Z, extent=(1, 1e2, 1, 1e2),
interpolation='nearest',cmap=cm.gist_rainbow, origin="lower")
ax1.set_yscale('log')
ax1.set_xscale('log')
ax1.set_xlim([1, x.max()])
ax1.set_ylim([1, y.max()])
ax1.set_title('log scale')
#make colorbar
divider1 = make_axes_locatable(ax1)
ax_cb1 = divider1.new_horizontal(size="5%", pad=0.05)
fig.add_axes(ax_cb1)
fig.colorbar(im1, cax = ax_cb1, ax=ax1)
plt.tight_layout()
plt.show()
Upvotes: 1