简体   繁体   中英

How do I change the x and y axes in subplots using python?

So I am trying to use this data: [1,2,3], [3,4,5] to plot a vertical bar chart, horizontal bar chart and a blank plot in one pyplot figure that would look like the image in this example:

在此处输入图片说明

but my code so far plots slightly differently as seen here. Look at the x-axis on bar chart 1 and y-axis on horizontal bar chart 2. I'm trying to get bar chart 1 x-axis to look like the y-axis on barh. Now the numbers are not in decimals (eg 1.0,2.0) and there are no numbers shown for 1.5,2.5 and 3.5. (I made some progress thanks to unutbu's explanation):

another updated image

Please see my updated code below, I am totally new to plotting and still trying to understand how this works:

import matplotlib.pyplot as plt
import numpy as np
plt.close()
fig, ax = plt.subplots(ncols=3)

sid = [1, 2, 3]
bel = [3, 4, 5]

y_pos = np.arange(len(sid))+1.5
ax[0].bar(y_pos, bel, align='center', alpha=0.5)
ax[0].set_xticks(y_pos, sid)
ax[0].set_xlim(1.0,4.0)
ax[0].set_ylim(0, 5)

y_pos = np.arange(len(sid)) + 1
ax[1].barh(y_pos, bel, height=0.9, align='edge', alpha=0.5)
ax[1].set_yticks(np.linspace(1, 4, 7))
ax[1].set_xticks(np.arange(0,6,1))
ax[1].set_ylim(1, 4)

sid = []
bel = []
y_pos = np.arange(len(sid))
ax[2].barh(y_pos, bel, align='center', alpha=0.5)
ax[2].set_yticks([0.0,0.2,0.4,0.6,0.8,1.0])
ax[2].set_xticks([0.0,0.2,0.4,0.6,0.8,1.0])
ax[2].set_ylim(0, 1)

plt.tight_layout()
plt.show()

Let's focus on the middle axes. You could use

y_pos = np.arange(len(sid))+1
plt.barh(y_pos, bel, height=0.9, align='edge', alpha=0.5)
plt.yticks(np.linspace(1, 4, 7))
plt.ylim(1, 4)

to produce the desired result. Notice that adding 1 to y_pos makes y_pos equal to array([1, 2, 3]) since adding a constant to a NumPy array adds that constant to each element in the array:

In [11]: np.arange(len(sid))
Out[11]: array([0, 1, 2])

In [12]: np.arange(len(sid))+1
Out[12]: array([1, 2, 3])

Thus, plt.barh(y_pos, ..., align='edge') places the bottom edge of the bars at y-locations 1, 2, 3.


np.linspace(1, 4, 7) generates 7 equally spaced values between 1 and 4:

In [13]: np.linspace(1, 4, 7)
Out[13]: array([1. , 1.5, 2. , 2.5, 3. , 3.5, 4. ])

plt.yticks(np.linspace(1, 4, 7)) tells matplotlib to label those locations.


plt.ylim(1, 4) sets the y-limits of the y-axis to range from 1 to 4.


On a stylistic note, you might want to consider switching to the "object-oriented" style of matplotlib programming . Instead of callling plt.subplot(1, 3, 2) to activate the second of 3 axes, you could use

fig, ax = plt.subplots(ncols=3)

to generate the 3 axes. This gives you an object ax which is a sequence of 3 axes.

The attraction of coding this way is that you now have a "physical" object to which you can send commands.

Before, when you focus on a single line like

plt.barh(y_pos, bel, height=0.9, align='edge', alpha=0.5)

it was not immediately clear on which axes the bar chart will appear. Now, using the object-oriented matplotlib coding style, this command would be

ax[1].barh(y_pos, bel, height=0.9, align='edge', alpha=0.5)

so you would know immediately that the second axes is being drawn upon.

Although it may be a little more verbose (ie more typing), as your programs grow in complexity, I think you'll find the "object-oriented" style produces clearer, more readable code.

Here is what your code would look like:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(ncols=3)

sid = [1, 2, 3]
bel = [3, 4, 5]

y_pos = np.arange(len(sid)) + 1
ax[0].bar(y_pos, bel, width=0.9, align='edge', alpha=0.5)
ax[0].set_xticks(np.linspace(1, 4, 7))
ax[0].set_ylim(0, 5)

ax[1].barh(y_pos, bel, height=0.9, align='edge', alpha=0.5)
ax[1].set_yticks(np.linspace(1, 4, 7))
ax[1].set_xticks(np.arange(0,6,1))
ax[1].set_ylim(1, 4)

sid = []
bel = []
y_pos = np.arange(len(sid))
ax[2].barh(y_pos, bel, align='center', alpha=0.5)
ax[2].set_yticks([0.0,0.2,0.4,0.6,0.8,1.0])
ax[2].set_xticks([0.0,0.2,0.4,0.6,0.8,1.0])
ax[2].set_ylim(0, 1)

plt.tight_layout()
plt.show()

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM