How can I change the data on one axis?
I'm making some spectrum analysis on some data and my x-axis is the index of some matrix. I'd like to change it so that the x-axis becomes the data itself.
I'm using the imshow() to plot the data (I have a matrix whose elements are some intensity, the y axes are their detector-source correspondent pair and the x-axis should be their frequency).
The code for it is written down here:
def pltspec(dOD, self):
idx = 0
b = plt.psd(dOD[:,idx],Fs=self.fs,NFFT=512)
B = np.zeros((2*len(self.Chan),len(b[0])))
for idx in range(2*len(self.Chan)):
b = plt.psd(dOD[:,idx],Fs=self.fs,NFFT=512)
B[idx,:] = 20*log10(b[0])
fig = plt.figure()
ax = fig.add_subplot(111)
plt.imshow(B, origin = 'lower')
plt.colorbar()
locs, labels = xticks(find(b[1]), b[1])
plt.axis('tight')
ax.xaxis.set_major_locator(MaxNLocator(5))
I think if there's a way of interchanging the index of some array with its value, my problem would be solved.
I've managed to use the line locs, labels = xticks(find(b[1]), b[1]). But with it on my graph my axis interval just isn't right... I think it has something to do with the MaxNLocator (which I used to decrease the number of ticks).
And if I use the xlim, I can set the figure to be what I want, but the x axis is still the same (on that xlim I had to use the original data to set it right).
What am I doing wrong?
Yes, you can use the xticks method exemplified in this example.
There are also more sophisticated ways of doing it. See ticker.
Related
I have a scatter plot graph with a bunch of random x, y coordinates. Currently the Y-Axis starts at 0 and goes up to the max value. I would like the Y-Axis to start at the max value and go up to 0.
points = [(10,5), (5,11), (24,13), (7,8)]
x_arr = []
y_arr = []
for x,y in points:
x_arr.append(x)
y_arr.append(y)
plt.scatter(x_arr,y_arr)
There is a new API that makes this even simpler.
plt.gca().invert_xaxis()
and/or
plt.gca().invert_yaxis()
DisplacedAussie's answer is correct, but usually a shorter method is just to reverse the single axis in question:
plt.scatter(x_arr, y_arr)
ax = plt.gca()
ax.set_ylim(ax.get_ylim()[::-1])
where the gca() function returns the current Axes instance and the [::-1] reverses the list.
You could also use function exposed by the axes object of the scatter plot
scatter = plt.scatter(x, y)
ax = scatter.axes
ax.invert_xaxis()
ax.invert_yaxis()
Use matplotlib.pyplot.axis()
axis([xmin, xmax, ymin, ymax])
So you could add something like this at the end:
plt.axis([min(x_arr), max(x_arr), max(y_arr), 0])
Although you might want padding at each end so that the extreme points don't sit on the border.
If you're in ipython in pylab mode, then
plt.gca().invert_yaxis()
show()
the show() is required to make it update the current figure.
Another similar method to those described above is to use plt.ylim for example:
plt.ylim(max(y_array), min(y_array))
This method works for me when I'm attempting to compound multiple datasets on Y1 and/or Y2
using ylim() might be the best approach for your purpose:
xValues = list(range(10))
quads = [x** 2 for x in xValues]
plt.ylim(max(quads), 0)
plt.plot(xValues, quads)
will result:
Alternatively, you can use the matplotlib.pyplot.axis() function, which allows you inverting any of the plot axis
ax = matplotlib.pyplot.axis()
matplotlib.pyplot.axis((ax[0],ax[1],ax[3],ax[2]))
Or if you prefer to only reverse the X-axis, then
matplotlib.pyplot.axis((ax[1],ax[0],ax[2],ax[3]))
Indeed, you can invert both axis:
matplotlib.pyplot.axis((ax[1],ax[0],ax[3],ax[2]))
If using matplotlib you can try:
matplotlib.pyplot.xlim(l, r)
matplotlib.pyplot.ylim(b, t)
These two lines set the limits of the x and y axes respectively. For the x axis, the first argument l sets the left most value, and the second argument r sets the right most value. For the y axis, the first argument b sets the bottom most value, and the second argument t sets the top most value.
I have a scatter plot graph with a bunch of random x, y coordinates. Currently the Y-Axis starts at 0 and goes up to the max value. I would like the Y-Axis to start at the max value and go up to 0.
points = [(10,5), (5,11), (24,13), (7,8)]
x_arr = []
y_arr = []
for x,y in points:
x_arr.append(x)
y_arr.append(y)
plt.scatter(x_arr,y_arr)
There is a new API that makes this even simpler.
plt.gca().invert_xaxis()
and/or
plt.gca().invert_yaxis()
DisplacedAussie's answer is correct, but usually a shorter method is just to reverse the single axis in question:
plt.scatter(x_arr, y_arr)
ax = plt.gca()
ax.set_ylim(ax.get_ylim()[::-1])
where the gca() function returns the current Axes instance and the [::-1] reverses the list.
You could also use function exposed by the axes object of the scatter plot
scatter = plt.scatter(x, y)
ax = scatter.axes
ax.invert_xaxis()
ax.invert_yaxis()
Use matplotlib.pyplot.axis()
axis([xmin, xmax, ymin, ymax])
So you could add something like this at the end:
plt.axis([min(x_arr), max(x_arr), max(y_arr), 0])
Although you might want padding at each end so that the extreme points don't sit on the border.
If you're in ipython in pylab mode, then
plt.gca().invert_yaxis()
show()
the show() is required to make it update the current figure.
Another similar method to those described above is to use plt.ylim for example:
plt.ylim(max(y_array), min(y_array))
This method works for me when I'm attempting to compound multiple datasets on Y1 and/or Y2
using ylim() might be the best approach for your purpose:
xValues = list(range(10))
quads = [x** 2 for x in xValues]
plt.ylim(max(quads), 0)
plt.plot(xValues, quads)
will result:
Alternatively, you can use the matplotlib.pyplot.axis() function, which allows you inverting any of the plot axis
ax = matplotlib.pyplot.axis()
matplotlib.pyplot.axis((ax[0],ax[1],ax[3],ax[2]))
Or if you prefer to only reverse the X-axis, then
matplotlib.pyplot.axis((ax[1],ax[0],ax[2],ax[3]))
Indeed, you can invert both axis:
matplotlib.pyplot.axis((ax[1],ax[0],ax[3],ax[2]))
If using matplotlib you can try:
matplotlib.pyplot.xlim(l, r)
matplotlib.pyplot.ylim(b, t)
These two lines set the limits of the x and y axes respectively. For the x axis, the first argument l sets the left most value, and the second argument r sets the right most value. For the y axis, the first argument b sets the bottom most value, and the second argument t sets the top most value.
I am creating a plot based on a DataFrame:
cg = sns.clustermap(df_correlations.T)
The problem is that the x and y axis have unwanted labels in it which come from a hierarchical index. Thus I want to try and remove those labels e.g. like this:
ax = cg.fig.gca()
ax.set_xlabel('')
ax.set_ylabel('')
But this has no effect. How can I remove the labels on the x and y axis?
Without a mcve of the issue it's hard to know where the labels come from (I don't know how the dataframe needs to look like such that labels are produced, because by default there should not be any labels.) However, the labels can be set - and therefore also set to an empty string - using the known methods .set_xlabel and .set_ylabel of the heatmap axes of the cluster grid.
So if g is a ClusterGrid instance,
g = sns.clustermap(...)
you can get the heatmap axes via
ax = g.ax_heatmap
and then use any method you like to manipulate this matplotlib axes.
ax.set_xlabel("My Label")
ax.set_ylabel("")
Turn off xticklabel, and yticklabel will address your problem.
sns.clustermap(df,yticklabels=False,xticklabels=False)
try plt.axis('off'), it may solve your problem.
I'm trying to plot the contour map of a given function f(x,y), but since the functions output scales really fast, I'm losing a lot of information for lower values of x and y. I found on the forums to work that out using vmax=vmax, it actually worked, but only when plotted for a specific limit of x and y and levels of the colormap.
Say I have this plot:
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
u = np.linspace(-2,2,1000)
x,y = np.meshgrid(u,u)
z = (1-x)**2+100*(y-x**2)**2
cont = plt.contour(x,y,z,500,colors='black',linewidths=.3)
cont = plt.contourf(x,y,z,500,cmap="jet",vmax=100)
plt.colorbar(cont)
plt.show
I want to uncover whats beyond the axis limits keeping the same scale, but if I change de x and y limits to -3 and 3 I get:
See how I lost most of my levels since my max value for the function at these limits are much higher. A work around to this problem is to increase the levels to 1000, but that takes a lot of computational time.
Is there a way to plot only the contour levels that I need? That is, between 0 and 100.
An example of a desired output would be:
With the white space being the continuation of the plot without resizing the levels.
The code I'm using is the one given after the first image.
There are a few possible ideas here. The one I very much prefer is a logarithmic representation of the data. An example would be
from matplotlib import ticker
fig = plt.figure(1)
cont1 = plt.contourf(x,y,z,cmap="jet",locator=ticker.LogLocator(numticks=10))
plt.colorbar(cont1)
plt.show()
fig = plt.figure(2)
cont2 = plt.contourf(x,y,np.log10(z),100,cmap="jet")
plt.colorbar(cont2)
plt.show()
The first example uses matplotlibs LogLocator functions. The second one just directly computes the logarithm of the data and plots that normally.
The third example just caps all data above 100.
fig = plt.figure(3)
zcapped = z.copy()
zcapped[zcapped>100]=100
cont3 = plt.contourf(x,y,zcapped,100,cmap="jet")
cbar = plt.colorbar(cont3)
plt.show()
I have an image plot, representing a matrix, with two axes. The y axis on th left of my image plot represents the rows and the x axis represents the column, while each grid cell represents the value as a function of x and y.
I'd like to plot my y-axis in another form on the right side of my image plot, which takes on much smaller values, but should still be in the same positions as the y-axis on the left, as the values are just different forms of one another. The problem is that when I use fig.twinx()and go to plot the y axis, it doesn't even show up! Does anyone know what's gong on? Thanks.
Current code:
# Setup the figure
fig5 = pyplot.figure(5, figsize=(10,9), facecolor='white')
pyplot.gcf().clear()
# plt.rc('xtick', labelsize=20)
# plt.rc('ytick', labelsize=20)
plt.rcParams.update({'font.size': 18})
fig5ax = pyplot.axes()
# Code to calculate extent based on min/max range and my x values
implot = pyplot.imshow(valgrid, extent=MyExtent , aspect='auto', vmin = myVmin, vmax = myVmax)
fig5ax.yaxis.set_major_formatter(plt.ticker.FixedFormatter([str(x) for x in ranges]))
fig5ax.yaxis.set_major_locator(plt.ticker.FixedLocator(ranges))
fig5Ax2 = fig5ax.twinx()
fig5Ax2.yaxis.set_major_formatter(plt.ticker.FixedFormatter([str(x) for x in time]))
# Setting locater the same as ranges, because I want them to line up
# as they are different forms of the same y value
fig5Ax2.yaxis.set_major_locator(plt.ticker.FixedLocator(ranges))
pyplot.show()
The answer was:
fig5Ax2.yaxis.set_view_interval(minRange, maxRange)