Python: How To Add A Secondary X Axis For A Single Trace?
Solution 1:
Further to your positive comment regarding plotly, here is an example of how to achieve a multi-xaxis for your dataset.
The code is a lot simpler than it looks. The code appears 'lengthy' due to the way I've formatted the dicts for easier reading.
The key elements are:
- Adding a cumulative sum of the
timecolumn (time_c) for use onxaxis2. - Adding a hidden trace which aligns to
xaxis, and your time data which aligns toxaxis2. Without the hidden trace, either both axes do not appear, or they appear but are not aligned, due to only one trace being plotted.
(Updated) Sample Code:
The following code has been updated to address the issue OP was having with a larger (70k row) dataset.
The key change is an update to the layout['xaxis'] and layout['xaxis2'] dicts to contain 'type': 'category', 'nticks' and defined 'range' keys.
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')
Example Graph (original dataset):
I've intentionally left out any additional appear configuration for code simplicity. However, referring to the top level plotly docs, the graphs are highly configurable.
Example Graph (new dataset):
This graph uses the (larger, 70k row) synthesised dataset from the other answer.
Solution 2:
Although generally discouraged, I'll post another answer to address the new dataset, as the previous answer works, given the original dataset.
This example diverges from the original request of a secondary x-axis for two reasons:
- Due to the size of the (new) dataset, plotting a 'hidden' layer of data is not optimal.
- For a secondary x-axis to display properly, a second trend must be plotted, and given the previous reason, this is no longer an option.
Therefore, a different approach has been taken - that of combined labeling of the x-axis. Rather than plotting two axes, the single x-axis features both required labels.
Example Graph:
Note: This is (obviously) synthesised data, in order to achieve the number of rows (70k) in the updated question.
Sample Code:
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 ---defcreate_labels(x):
"""Function to create xaxis labels."""returnf"({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')



Post a Comment for "Python: How To Add A Secondary X Axis For A Single Trace?"