【问题标题】:Python: How to add a secondary x axis for a single trace?Python:如何为单个轨迹添加辅助 x 轴?
【发布时间】:2020-09-16 05:36:44
【问题描述】:

我有一个 DataFrame(请参阅下面的“测试数据”部分),我想添加一个辅助 x 轴(在顶部)。但是这个轴必须从 0 到 38.24(ms)。这是“时间”列中所有值的总和。它表示执行 4 个推理所需的总时间。 到目前为止,我已经尝试了 'twinx()' 没有成功。

我该怎么做?有可能还是我缺乏信息?

测试数据:

raw_data = {'Time': [21.9235, 4.17876, 4.02168, 3.81504, 4.2972],
            'TPU': [33.3, 33.3, 33.3, 33.3, 33.3],
            'CPU': [32, 32, 32, 32, 32],
            'MemUsed': [435.92, 435.90, 436.02, 436.02, 436.19]}

df_m=pd.DataFrame(raw_data, columns = ['Time', 'TPU', 'CPU', 'MemUsed'])

df_m
##Sum of all values in column Time(ms)
(df_m.iloc[:, 0].sum())

##Time per inference(ms)
ax = df_m.plot(kind = 'line', y = 'MemUsed', grid = True)
ax.set_xlabel("NUMBER OF INFERENCES")
ax.set_ylabel("MemUsed(MB)")

我尝试过的:

ax = df_m.plot(kind = 'line', y = 'MemUsed', grid = True)
df_m.plot(kind='line', ax=ax.twinx(), secondary_x=range(0, 39))
ax.set_xlabel("NUMBER OF INFERENCES")
ax.set_ylabel("MemUsed(MB)")

输出图表:

大桌子长什么样子

【问题讨论】:

  • 有情节可以选择吗?
  • 当然。虽然我从来没有用过。但是图表看起来很漂亮。
  • 优秀。我同意,情节图可能非常惊人。我已经为您提供了一个答案,并为问题的完整性投了赞成票。

标签: python python-3.x pandas dataframe data-visualization


【解决方案1】:

除了您对 plotly 的积极评价之外,这里是一个如何为您的数据集实现多 xaxis 的示例。

代码比看起来简单得多。由于我已格式化 dicts 以便于阅读,代码显得“冗长”。

关键要素是:

  • 添加 time 列 (time_c) 的累积总和以用于 xaxis2
  • 添加与xaxis 对齐的隐藏轨迹,以及与xaxis2 对齐的时间数据。如果没有隐藏的轨迹,则两个轴都不会出现,或者它们会出现但未对齐,因为只绘制了一条轨迹。

(更新)示例代码:

以下代码已更新,以解决 OP 在处理更大(70k 行)数据集时遇到的问题。

密钥更改是对 layout['xaxis']layout['xaxis2'] 字典的更新,以包含 'type': 'category''nticks' 和定义的 'range' 密钥。

import pandas as pd
from plotly.offline import plot

# Create the dataset.
raw_data = {'time': [21.9235, 4.17876, 4.02168, 3.81504, 4.2972],
            'tpu': [33.3, 33.3, 33.3, 33.3, 33.3],
            'cpu': [32, 32, 32, 32, 32],
            'memused': [435.92, 435.90, 436.02, 436.02, 436.19]}

df = pd.DataFrame(raw_data)
df['time_c'] = df['time'].cumsum().round(2)

# Plotting code.
data = []
layout = {'margin': {'t': 105},
          'title': {'text': 'Example Showing use of Secondary X-Axis', 
                    'y': 0.97}}

# Create a (hidden) trace for the xaxis.
data.append({'x': df.index,
             'y': df['memused'],
             'showlegend': False,
             'mode': 'markers', 
             'marker': {'size': 0.001}})
# Create the visible trace for xaxis2.
data.append({'x': df['time_c'],
             'y': df['memused'],
             'xaxis': 'x2',
             'name': 'Inference'})

# Configure graph layout.
nticks = int(df.shape[0] // (df.shape[0] * 0.05))
layout['xaxis'] = {'title': 'Number of Inferences',
                   'nticks': nticks,
                   'range': [df.index.min(), df.index.max()],
                   'tickangle': 45,
                   'type': 'category'}
layout['xaxis2'] = {'title': 'Time(ms)', 
                    'nticks': nticks,
                    'overlaying': 'x1', 
                    'range': [df['time_c'].min(), df['time_c'].max()],
                    'side': 'top', 
                    'tickangle': 45,
                    'type': 'category'}
layout['yaxis'] = {'title': 'Memory Used (MB)'}

fig = {'data': data, 'layout': layout}
plot(fig, filename='/path/to/graph.html')

示例图(原始数据集):

为了简化代码,我有意省略了任何额外的外观配置。但是,参考顶级 plotly docs,这些图表是高度可配置的。

示例图(新数据集):

此图使用来自另一个答案的(更大的,70k 行)合成数据集。

【讨论】:

  • 我在使用大数据框时遇到问题
  • 这可能是因为数据实际上被绘制了两次;我想我有一个解决办法。数据集是否与您在问题中发布的相似?多少行?我有一个不同的 xaxis 方法的想法。
  • 是的,类似。我会放一张图片。有70000行
  • 好了。我已经更新了原始答案中的代码和图表,以解决您遇到的问题。此外,我已经发布了第二个答案 (sshhhh) 为您提供另一种选择,这样就无需绘制 两个 每个轨迹的 70k 数据点。希望这会有所帮助!
  • 成功了。它更快。我会分析你的代码。
【解决方案2】:

虽然通常不鼓励,但我会发布另一个答案来解决新数据集,因为之前的答案在给定原始数据集的情况下有效。

此示例与辅助 x 轴的原始请求不同,原因有两个:

  1. 由于(新)数据集的大小,绘制“隐藏”数据层并不是最佳选择。
  2. 要正确显示第二个 x 轴,必须绘制第二个趋势,鉴于前面的原因,这不再是一个选项。

因此,采用了一种不同的方法 - x 轴的组合标签。而不是绘制两个轴,单个 x 轴具有两个必需的标签。

示例图表:

注意:这是(显然)合成数据,为了达到更新问题的行数(70k)。

示例代码:

import numpy as np
import pandas as pd
from plotly.offline import plot

# Synthesised dataset. (This code can be ignored.)
np.random.seed(0)
a = np.random.exponential(size=70000)*4
t = pd.Series(a).rolling(window=2000, min_periods=50).mean().to_numpy()
r = np.arange(70000).astype(str)
m = t*100

df = pd.DataFrame({'run': r, 
                   'time': t,
                   'memused': m}).dropna()

# Add cumulative time column.
df['time_c'] = df['time'].cumsum().round(1)


# --- Graphing code starts here ---

def create_labels(x):
    """Function to create xaxis labels."""
    return f"({x['run']}): {x['time_c']}"

# Create xaxis labels.
df['xaxis'] = df.apply(create_labels, axis=1)

# Create the graph.
data = []
layout = {'title': 'Combined X-Axis Labeling'}
data.append({'x': df['xaxis'], 
             'y': df['memused']})

layout['xaxis'] = {'title': '(Inference): Cumulative Time (ms)', 
                   'type': 'category', 
                   'nticks': df.shape[0] // 3500,
                   'tickangle': 45}
layout['yaxis'] = {'title': 'Memory Used (MB)'}


fig = {'data': data, 'layout': layout}
plot(fig, filename='/path/to/graph.html')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-05
    • 2016-12-01
    • 1970-01-01
    • 2015-07-22
    • 1970-01-01
    相关资源
    最近更新 更多