【问题标题】:matplotlib: plotting more than one figure at oncematplotlib:一次绘制多个图形
【发布时间】:2020-01-10 20:37:06
【问题描述】:

我正在使用具有相同列结构(数字和类型)的 3 个熊猫 dataframes,只是数据集是针对不同年份的。

我想为每个数据帧绘制ECDF,但每次我这样做时,我都会单独进行(缺乏 python 技能)。同样,其中一个数字(2018 年)在 x-axis 上的缩放比例不同,这使得比较有点困难。这是我的做法。

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    from empiricaldist import Cdf

    df1 = pd.read_csv('2016.csv')
    df2 = pd.read_csv('2017.csv')
    df3 = pd.read_csv('2018.csv')

    #some info about the dfs
    df1.columns.values
    array(['id', 'trip_id', 'distance', 'duration', 'speed', 'foot', 'bike',
       'car', 'bus', 'metro', 'mode'], dtype=object)

    modal_class = df1['mode']
    print(modal_class[:5])
    0         bus
    1         metro
    2         bike
    3         foot
    4         car

    def decorate_ecdf(title, x, y):
        plt.xlabel(x)
        plt.ylabel(y)
        plt.title(title)

    #plotting the ecdf for 2016 dataset
    for name, group in df1.groupby('mode'):
        Cdf.from_seq(group.speed).plot()    
    title, x, y = 'Speed distribution by travel mode (April 2016)','speed (m/s)', 'ECDF'
    decorate_ecdf(title,x,y)

    #plotting the ecdf for 2017 dataset
    for name, group in df2.groupby('mode'):
        Cdf.from_seq(group.speed).plot()    
    title, x, y = 'Speed distribution by travel mode (April 2017)','speed (m/s)', 'ECDF'
    decorate_ecdf(title,x,y)

    #plotting the ecdf for 2018 dataset
    for name, group in df3.groupby('mode'):
        Cdf.from_seq(group.speed).plot()    
    title, x, y = 'Speed distribution by travel mode (April 2018)','speed (m/s)', 'ECDF'
    decorate_ecdf(title,x,y)

输出:

我很确定这不是 pythonist 的做法,而是一种完成工作的肮脏方式。您还可以查看 2018 年图在 x 轴上的不同缩放比例。

  1. 有没有办法强制所有数字都以相同的方式缩放?
  2. 如何重写我的代码,以便通过调用一次函数来绘制图形?

【问题讨论】:

  • 这个问题已经被问过好几次了。搜索网站。我看看能不能找到链接。答案的核心是使用带有plt.subplot() 的子图,然后设置参数以跨子图共享 x 轴。

标签: python python-3.x matplotlib pandas-groupby


【解决方案1】:

使用 pyplot 时,您可以使用 plt.plot() 的隐式方法进行绘图,或者您可以使用显式方法,通过使用 fig, ax = plt.subplots() 创建和调用图形和轴对象。在我看来,这里发生的事情是使用隐式方法的副作用。

例如,您可以使用两个pd.DataFrame.plot() 命令并通过将返回的轴提供给另一个函数来让它们共享同一轴。

foo = pd.DataFrame(dict(a=[1,2,3], b=[4,5,6]))
bar = pd.DataFrame(dict(c=[3,2,1], d=[6,5,4]))
ax = foo.plot()
bar.plot(ax=ax) # ax object is updated
ax.plot([0,3], [1,1], 'k--')

您也可以预先创建图形和轴对象,并根据需要提供。此外,拥有多个绘图命令是完美的文件。通常,我的代码 25% 是工作,75% 是在摆弄情节。不要试图变得聪明而失去可读性。

fig, axes = plt.subplots(nrows=3, ncols=1, sharex=True)
# In this case, axes is a numpy array with 3 axis objects
# You can access the objects with indexing
# All will have the same x range
axes[0].plot([-1, 2], [1,1])
axes[1].plot([-2, 1], [1,1])
axes[2].plot([1,3],[1,1])

因此,您可以将这两个 sn-ps 组合到您自己的代码中。首先,创建图形和轴对象,然后绘制每个数据框,但使用关键字ax 为它们提供正确的轴。

另外,假设您有三个轴对象并且它们具有不同的x 限制。您可以将它们全部获取,然后将三个设置为具有相同的最小值和相同的最大值。例如:

axis_list = [ax1, ax2, ax3] # suppose you created these separately and want to enforce the same axis limits
minimum_x = min([ax.get_xlim()[0] for ax in axis_list])
maximum_x = max([ax.get_xlim()[1] for ax in axis_list])
for ax in axis_list:
    ax.set_xlim(minimum_x, maximum_x)

【讨论】:

  • 感谢您的详细解答。我觉得它非常有帮助。
猜你喜欢
  • 1970-01-01
  • 2019-04-19
  • 2017-01-29
  • 1970-01-01
  • 1970-01-01
  • 2010-11-26
  • 1970-01-01
  • 2023-01-20
  • 2019-12-22
相关资源
最近更新 更多