How to invert the x or y axis - python

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.

Related

Can I reverse xaxis in Aitoff projection supported by matplotlib? [duplicate]

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.

How can I put the largest proportion on the top in my horizontal bar chart in Matplotlib? [duplicate]

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.

How can I reduce whitespace in Python plot?

I am plotting 2 shapefiles (converted to geopandas dataframe) using this. But there is too much whitespace. How can I reduce it to fill the box more with the map? The xlim and ylim doesn't seem to have any impact
f, ax = plt.subplots(1, figsize=(8, 8))
polydatx.plot(ax = ax, column = 'Elev_Avg', cmap='OrRd', scheme='quantiles')
segdatx.plot(ax = ax)
ax.grid(False)
ax.set_ylim(47, 47.3)
plt.axis('equal');
The problem lies in calling
plt.axis('equal')
after setting the new ylim.
From the docs:
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.
In your case I would adjust the figure size to some rectangle, not a square and use axis('scaled').

Setting font size in matplotlib plot [duplicate]

I have too many ticks on my graph and they are running into each other.
How can I reduce the number of ticks?
For example, I have ticks:
1E-6, 1E-5, 1E-4, ... 1E6, 1E7
And I only want:
1E-5, 1E-3, ... 1E5, 1E7
I've tried playing with the LogLocator, but I haven't been able to figure this out.
Alternatively, if you want to simply set the number of ticks while allowing matplotlib to position them (currently only with MaxNLocator), there is pyplot.locator_params,
pyplot.locator_params(nbins=4)
You can specify specific axis in this method as mentioned below, default is both:
# To specify the number of ticks on both or any single axes
pyplot.locator_params(axis='y', nbins=6)
pyplot.locator_params(axis='x', nbins=10)
To solve the issue of customisation and appearance of the ticks, see the Tick Locators guide on the matplotlib website
ax.xaxis.set_major_locator(plt.MaxNLocator(3))
would set the total number of ticks in the x-axis to 3, and evenly distribute them across the axis.
There is also a nice tutorial about this
If somebody still gets this page in search results:
fig, ax = plt.subplots()
plt.plot(...)
every_nth = 4
for n, label in enumerate(ax.xaxis.get_ticklabels()):
if n % every_nth != 0:
label.set_visible(False)
There's a set_ticks() function for axis objects.
in case somebody still needs it, and since nothing
here really worked for me, i came up with a very
simple way that keeps the appearance of the
generated plot "as is" while fixing the number
of ticks to exactly N:
import numpy as np
import matplotlib.pyplot as plt
f, ax = plt.subplots()
ax.plot(range(100))
ymin, ymax = ax.get_ylim()
ax.set_yticks(np.round(np.linspace(ymin, ymax, N), 2))
The solution #raphael gave is straightforward and quite helpful.
Still, the displayed tick labels will not be values sampled from the original distribution but from the indexes of the array returned by np.linspace(ymin, ymax, N).
To display N values evenly spaced from your original tick labels, use the set_yticklabels() method. Here is a snippet for the y axis, with integer labels:
import numpy as np
import matplotlib.pyplot as plt
ax = plt.gca()
ymin, ymax = ax.get_ylim()
custom_ticks = np.linspace(ymin, ymax, N, dtype=int)
ax.set_yticks(custom_ticks)
ax.set_yticklabels(custom_ticks)
If you need one tick every N=3 ticks :
N = 3 # 1 tick every 3
xticks_pos, xticks_labels = plt.xticks() # get all axis ticks
myticks = [j for i,j in enumerate(xticks_pos) if not i%N] # index of selected ticks
newlabels = [label for i,label in enumerate(xticks_labels) if not i%N]
or with fig,ax = plt.subplots() :
N = 3 # 1 tick every 3
xticks_pos = ax.get_xticks()
xticks_labels = ax.get_xticklabels()
myticks = [j for i,j in enumerate(xticks_pos) if not i%N] # index of selected ticks
newlabels = [label for i,label in enumerate(xticks_labels) if not i%N]
(obviously you can adjust the offset with (i+offset)%N).
Note that you can get uneven ticks if you wish, e.g. myticks = [1, 3, 8].
Then you can use
plt.gca().set_xticks(myticks) # set new X axis ticks
or if you want to replace labels as well
plt.xticks(myticks, newlabels) # set new X axis ticks and labels
Beware that axis limits must be set after the axis ticks.
Finally, you may wish to draw only an arbitrary set of ticks :
mylabels = ['03/2018', '09/2019', '10/2020']
plt.draw() # needed to populate xticks with actual labels
xticks_pos, xticks_labels = plt.xticks() # get all axis ticks
myticks = [i for i,j in enumerate(b) if j.get_text() in mylabels]
plt.xticks(myticks, mylabels)
(assuming mylabels is ordered ; if it is not, then sort myticks and reorder it).
xticks function auto iterates with range function
start_number = 0
end_number = len(data you have)
step_number = how many skips to make from strat to end
rotation = 90 degrees tilt will help with long ticks
plt.xticks(range(start_number,end_number,step_number),rotation=90)
if you want 10 ticks:
for y axis: ax.set_yticks(ax.get_yticks()[::len(ax.get_yticks())//10])
for x axis: ax.set_xticks(ax.get_xticks()[::len(ax.get_xticks())//10])
this simply gets your ticks and chooses every 10th of the list and sets it back to your ticks. you can change the number of ticks as you wish.
When a log scale is used the number of major ticks can be fixed with the following command
import matplotlib.pyplot as plt
....
plt.locator_params(numticks=12)
plt.show()
The value set to numticks determines the number of axis ticks to be displayed.
Credits to #bgamari's post for introducing the locator_params() function, but the nticks parameter throws an error when a log scale is used.

Changing axis values on a plot

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.

Categories

Resources