Issue
I have working code to generate plots showing x,y,z values for three parameters from an accelerometer, with side-by-side line and 3D plots for each:
from mpl_toolkits import mplot3d
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
#code here loads data into a dataframe df
fig = plt.figure(figsize=(10,8))
fig.suptitle(filename, fontsize=12)
for p in ('accel','angle','avelo')
i += 1
ax = fig.add_subplot(3, 2, i)
ax.plot(idx,df[p,'x'], label = "x")
ax.plot(idx,df[p,'y'], label = "y")
ax.plot(idx,df[p,'z'], label = "z")
ax.set_ylabel(p)
ax.legend(loc="best")
i += 1
ax = fig.add_subplot(3,2,i,projection='3d')
ax.plot3D(df[p,'x'],df[p,'y'],df[p,'z'],'black')
ax.scatter(df[p]['x'][0],df[p]['y'][0],df[p]['z'][0], c='green', marker='o', s=50)
ax.scatter(df[p]['x'].iloc[-1],df[p]['y'].iloc[-1],df[p]['z'].iloc[-1], c='red', marker='x', s=50)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.subplots_adjust(left=0.1,
bottom=0.1,
right=0.9,
top=0.9,
wspace=0.4,
hspace=0.1)
plt.show()
I want to make the line plots twice as wide as they are by default. Is there some way to do this with the existing add_subplot approach or do I have to rework the code to set up the plots with plt.subplots? All the examples I find assume the latter.
Solution
- The aspect of the subplots should be set during the creation of the figure and axes with
plt.subplots
.- I do not see a way to adjust the axes with
.add_subplot
- I do not see a way to adjust the axes with
- This answer was created by combining aspects of the following answer:
- Tested in
python 3.11.2
,matplotlib 3.7.1
import matplotlib.pyplot as plt
# create the figure and axes with specified width_ratios
fig, axes = plt.subplots(3, 2, figsize=(10, 10), width_ratios=[2, 1])
# remove the subplots to be set as 3d projections
axes[0, 1].remove()
axes[1, 1].remove()
axes[2, 1].remove()
# add the subplots back as 3d projections; rows, cols and index are relative to width_ratios
axes[0, 1] = fig.add_subplot(3, 3, 3, projection='3d')
axes[1, 1] = fig.add_subplot(3, 3, 6, projection='3d')
axes[2, 1] = fig.add_subplot(3, 3, 9, projection='3d')
cols = ['accel','angle','avelo']
# axes is a (3, 2) array; iterate through each set of subplots, and corresponding value from cols
for (ax_left, ax_right), col in zip(axes, cols):
# ax_left.plot(..., label='x')
# ax_left.plot(..., label='y')
# ax_left.plot(..., label='z')
ax_left.set_ylabel(col)
# ax_right.plot3d(...)
# ax_right.scatter(...)
# ax_right.scatter(...)
# move the z-axis to the left side, otherwise the label isn't visible
ax_right.zaxis._axinfo['juggled'] = (1, 2, 2)
ax_right.set_xlabel('x')
ax_right.set_ylabel('y')
ax_right.set_zlabel('z')
- Alternatively,
matplotlib.pyplot.subplot_mosaic
can be used to create Per-Axes subplot keyword arguments.
# create subplot mosaic with different keyword arguments
fig, ax = plt.subplot_mosaic("AB;CD;EF",
per_subplot_kw={('B', 'D', 'F'): {'projection': '3d'}},
gridspec_kw={'width_ratios': [2, 1],
'wspace': 0.1, 'hspace': 0.1},
figsize=(10, 10))
Answered By - Trenton McKinney
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.