I am creating subplot graphs using a for loop and when I turn on 'sharex', the x-labels for all the subplots are incorrect and match the last subplot. I want it to create a tick for each available label.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.DataFrame({
'letters' : ['A','A','A', 'B','B','B', 'C','C','C', 'D','D','D'],
'values' : [1, 2, 3, 3, 2, 1, 2, 3, 1, 2, 3, 4],
'options': ['O 1', 'O 2', 'O 3', 'O 3', 'O 2', 'O 1',
'O 2','O 3','O 1','O 2','O 3','O 4'],
})
list_letters = ['A', 'B', 'C', 'D']
fig,axes = plt.subplots(nrows = 1, ncols = len(list_letters), sharey = True, sharex = True)
for letter in list_letters:
index = list_letters.index(letter)
df2 = df[(df['letters'] == letter)]
sns.scatterplot(x="options", y="values",data = df2,
hue = 'options', ax=axes[index], legend = False)
axes[index].set_title(letter, rotation = 60, verticalalignment = 'bottom', ha = 'left')
I specifically made the dataframe so Option O1 has a value of 1 for all 'letters'. Same for O2, O3, and O4.
With shareX turned off (False):
Note how the values do not correspond correctly to the options, there are only 3 labels, and all the subplots match the last subplot order when shareX was off.
This is an issue with string x-axes. If I change 'options' column to numeric values, it all works fine. See here:
Is there any way to create subplots through for-loops, have ShareX turned on, and have four labels, O1, O2, O3, O4, and all the values correctly line up?
Unfortunately, there is currently no way to predetermine the units of an axes. This makes plotting of multiple categorical datasets cumbersome.
One hacky workaround is to plot something to the axes in the expected order and remove it afterwards. This is done via the prepare_axes
function in the code below.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({
'letters' : ['A','A','A', 'B','B','B', 'C','C','C', 'D','D','D'],
'values' : [1, 2, 3, 3, 2, 1, 2, 3, 1, 2, 3, 4],
'options': ['O 1', 'O 2', 'O 3', 'O 3', 'O 2', 'O 1',
'O 2','O 3','O 1','O 2','O 3','O 4'],
})
list_letters = ['A', 'B', 'C', 'D']
def prepare_axes(x, ax):
ax.autoscale(False)
line, = ax.plot(x, np.zeros(len(x)))
line.remove()
ax.relim()
ax.autoscale(True)
# determine all needed categoricals
uniqueoptions = df["options"].unique()
fig,axes = plt.subplots(nrows = 1, ncols = len(list_letters), sharey = True, sharex = True)
for letter in list_letters:
index = list_letters.index(letter)
df2 = df[(df['letters'] == letter)]
_, hue = np.unique(df2["options"].values, return_inverse=True)
prepare_axes(uniqueoptions, axes[index])
axes[index].scatter(x="options", y="values", c=hue, data = df2)
axes[index].set_title(letter, rotation = 60, verticalalignment = 'bottom', ha = 'left')
plt.show()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.