plt.setp 替代子图或如何为子图设置 x 轴上的文本旋转

Wak*_*nka 4 python matplotlib

我有这段代码,我可以在其中控制属性,例如:x 轴范围、标题、xlabel、ylabel、图例、网格、x 标签上的文本旋转:

#!/usr/bin/python
import datetime
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
from matplotlib.dates import DateFormatter
############################################
# generate data
x = np.arange(0,10)
y0 = np.arange(0,10)
y1 = np.random.rand(10)
y2 = np.random.rand(10)
############################################
# initialize (sub)plot(s)
fig, ax = plt.subplots()
############################################
# width of x axis
x_min_index = 0
x_max_index = 3

x_min = x[x_min_index]
x_max = x[x_max_index]
############################################
# create (sub)plot
l, = plt.plot(x,y0, label="plot1a")
l, = plt.plot(x,y1, label="plot1b")
l, = plt.plot(x,y2, label="plot1c")

# (sub)plot - set values
plt.title("plot1")
plt.xlabel('xlabel')
plt.ylabel('ylabel')
plt.legend()
plt.grid()
############################################
# apply for all (sub)plot(s)
plt.subplots_adjust(bottom=0.25)
############################################
# (sub)plot - get values
# plt.axis(x_min, x_max, y_min, y_max)
y_min = plt.axis()[2]
y_max = plt.axis()[3]
print y_min
print y_max
############################################
# (sub)plot - set values
# change only x values
# y values are set to same value
# plt.axis([x_min, x_max, y_min, y_max])

# (sub)plot - set values
# change only x values
plt.xlim(x_min, x_max)
############################################
# (sub)plot - get values
locs, labels = plt.xticks()
print locs
print labels
############################################
# (sub)plot - set values
plt.setp(labels, rotation=45)

plt.show()
Run Code Online (Sandbox Code Playgroud)

此代码返回此数字: 在此处输入图片说明

我希望能够控制所有这些属性,但为其创建多个子图,我的尝试在这里:

#!/usr/bin/python
import datetime
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
from matplotlib.dates import DateFormatter
############################################
# generate data
x = np.arange(0,10)
y0 = np.arange(0,10)
y1 = np.random.rand(10)
y2 = np.random.rand(10)
############################################
# initialize (sub)plot(s)
fig, axarr = plt.subplots(2)

# http://stackoverflow.com/questions/6541123/improve-subplot-size-spacing-with-many-subplots-in-matplotlib
fig.tight_layout()
############################################
# width of x axis
x_min_index = 0
x_max_index = 3

x_min = x[x_min_index]
x_max = x[x_max_index]
############################################
# 1st (sub)plot
line0 = axarr[0].plot(x,y1, label="plot1a")
line0 = axarr[0].plot(x,y2, label="plot1b")
line0 = axarr[0].legend()
line0 = axarr[0].set_title('plot1')
line0 = axarr[0].set_xlabel('xlabel1')
line0 = axarr[0].set_ylabel('ylabel1')
line0 = axarr[0].grid()
############################################
# 2st (sub)plot
line1 = axarr[1].plot(x,y0, label="plot2", color="red")
line1 = axarr[1].legend()
line1 = axarr[1].set_title('plot2')
line1 = axarr[1].set_xlabel('xlabel2')
line1 = axarr[1].set_ylabel('ylabel2')
line1 = axarr[1].grid()
############################################
# apply for all (sub)plot(s)
plt.subplots_adjust(bottom=0.25)
############################################
# OLD CODE
# (sub)plot - get values
# plt.axis(x_min, x_max, y_min, y_max)
# y_min = plt.axis()[2]
# y_max = plt.axis()[3]
# print y_min
# print y_max

# NEW ALTERNATIVE
l0_x_min, l0_x_max = axarr[0].get_xlim()
l0_y_min, l0_y_max = axarr[0].get_ylim()

l1_x_min, l1_x_max = axarr[1].get_xlim()
l1_y_min, l1_y_max = axarr[1].get_ylim()

print l0_x_min
print l0_x_max
print l0_y_min
print l0_y_max

print l1_x_min
print l1_x_max
print l1_y_min
print l1_y_max
############################################
# OLD CODE
# (sub)plot - set values
# change only x values
# y values are set to same value
# plt.axis([x_min, x_max, y_min, y_max])

# (sub)plot - set values
# change only x values
# plt.xlim(x_min, x_max)

# NEW ALTERNATIVE
axarr[0].set_xlim(x_min, x_max)
############################################
# OLD CODE
# (sub)plot - get values
# locs, labels = plt.xticks()
# print locs
# print labels

# NEW ALTERNATIVE
line0_xticks = axarr[0].get_xticks()
line0_labels = axarr[0].get_xticklabels()
print line0_xticks
print line0_labels

line1_xticks = axarr[1].get_xticks()
line1_labels = axarr[1].get_xticklabels()
print line1_xticks
print line1_labels
############################################
# OLD CODE
# (sub)plot - set values
# plt.setp(labels, rotation=45)

# NEW ALTERNATIVE
############################################
plt.show()
Run Code Online (Sandbox Code Playgroud)

此代码返回此数字: 在此处输入图片说明

此代码有一个限制,因为我无法在 x 轴上设置标签的旋转。我找不到可以执行此操作的子图的正确方法。到目前为止,我已经找到了以下相互对应的方法:

PLOT                                    SUBPLOTS
plt.axis()                              axarr[0].get_xlim(), axarr[0].get_ylim()
plt.axis([x_min, x_max, y_min, y_max])  axarr[0].set_xlim(x_min, x_max), axarr[0].set_ylim(y_min, y_max)
plt.xlim(x_min, x_max)                  axarr[0].set_xlim(x_min, x_max)
plt.xticks()                            axarr[0].get_xticks(), axarr[0].get_xticklabels()
plt.setp(labels, rotation=45)           ???
plt.title("plot1")                      axarr[0].set_title('plot1')
plt.grid()                              axarr[0].grid()
plt.legend()                            axarr[0].legend()
plt.xlabel('xlabel')                    axarr[0].set_xlabel('xlabel')
plt.ylabel('xlabel')                    axarr[0].set_ylabel('xlabel')
plt.plot(x,y, label="plot")             axarr[0].plot(x,y, label="plot")
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 除了图和子图之间的所有相应方法之外,是否存在类似的表?
  2. 可能更哲学的问题;为什么有两种不同的命名约定?
  3. 我通过运行下面的代码ipdb,点击选项卡,并写下熟悉的方法名称来创建这个表作为试错。有没有更好的办法?我可以想象一些比较方法返回类型、参数等的东西。
  4. 如何从一组中找到任何方法的替代方法?
  5. 最后,如何在子图下旋转 x 标签?

hit*_*tzg 6

我会试着一一回答你的问题。但在此之前,你需要了解情节和子情节之间没有区别。而情节通常是指在一个图中的单一轴,副区指的是一个数字多个轴中的一个。但是对于 matplotlib 它们都是轴实例。

plt通常是指pyplot模块(如果导入为import matplotlib.pyplot as plt)。这个模块有很多功能,比如你列出的功能,还有很多绘图功能(例如plotscatter, 等)。然而,这些只是为了方便,并在当前轴实例上调用相应的函数。以非常简化的方式plt.plot构建如下:

def plot(*args, **kwargs):
    ax = plt.gca()
    return ax.plot(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

不幸的是,命名并不一致。但总的来说,轴方法使用set_*and get_*,而plt函数则不使用。

这意味着您可以创建您发布的第一个图,使用fig, ax = plt.subplots(1)然后继续使用轴方法:ax.plot(...)等。

至于你的问题:

  1. 我不这么认为。但作为一般建议,我会尝试使用轴方法,因为它们提供了所有功能,而plt 等效项是有限的。
  2. matplotlib 的灵感来自于 Matlab 的绘图功能。这就是plt功能的来源。
  3. 我不确定是否有一个通用的方法来解决这个问题。通常可以通过名称来猜测事物(例如plt.title--> ax.set_title)。使用 matplotlib 通常也意味着手头有文档。
  4. 再次,根据经验或名称。但你没有必要。你也可以只用一个!
  5. plt.setp是一个辅助函数。它为艺术家列表设置一个属性(因此得名)。因此plt.setp(labels, rotation=45)执行以下操作:

    for i in labels:
        i.set_rotation(45)
    
    Run Code Online (Sandbox Code Playgroud)

    问题只是如何获得对标签列表的引用。您可以通过以下方式获取它们:

    labels = plt.xticklabels()
    
    Run Code Online (Sandbox Code Playgroud)

    或者

    labels = ax.get_xticklabels()
    
    Run Code Online (Sandbox Code Playgroud)