0

In this lollipop / stem plot showing an index value for two categories (left/right) per participant, the x labels are unequally distributed in relation to the x-ticks after rotating the labels:

Before rotating:
x-labels are not legible but centered around the x-tick

After rotating:
x-labels are legible but the first 7 labels are centered slightly right from the x-tick, whereas the last 16 labels are centered slightly left from the tick
Without line: plt.xticks(rotation = 'vertical', ha = 'right', rotation_mode='anchor')

The data:
df_LR = pd.read_csv("Index_for_stats_LeftRight_merge.csv")
pandas dataframe with separate columns for left and right

The plot:
Inspired by code from https://www.python-graph-gallery.com/184-lollipop-plot-with-2-groups. It creates the lollipop plot by combing plt.vlines and plt.scatter.

f, ax = plt.subplots(figsize=(10, 6))

# Reorder dataframe following the values of the first value:
df_LR = df_LR.sort_values(by='index_right')
my_range=range(1,len(df_LR.index)+1)
 
# The vertical plot is made using the vline function
plt.vlines(x=my_range, ymin=df_LR['index_left'], ymax=df_LR['index_right'], color='grey', alpha=0.4)
plt.scatter(my_range, df_LR['index_left'], color='#E68900', alpha=1, label='left')
plt.scatter(my_range, df_LR['index_right'], color='seagreen', alpha=1, label='right')
plt.legend()
 
# Add title and axis names
plt.xticks(rotation = 'vertical', ha = 'right', rotation_mode='anchor')
plt.xticks(my_range, df_LR['subject ID'])
plt.title("Index: left-right differences per participant", loc='left')
plt.ylabel('Index')
plt.xlabel('')

# Show graph
plt.show()

I tried adjusting the xticks line specifying rotation (swap 'vertical' for a float, swap ha = 'right' for 'left') but these changes are then only visible in the first 7 subjects displayed on the x-axis. It is as if something gets disrupted from sub-11 onwards.

Any ideas on how to solve this would be greatly appreciated!

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Eva
  • 1
  • 1

1 Answers1

0

Do the replacement first, and only then rotate (i.e. swap the positions of those two lines):

plt.xticks(my_range, df_LR['subject ID'])
plt.xticks(rotation = 'vertical', ha = 'right', rotation_mode='anchor')

Further note:

I see you first created a figure by f, ax = plt.subplots(figsize=(10, 6)), but then you proceed by using the pyplot interface. You are mixing the two possible interfaces. If you are going to use Matplotlib a lot, you may be interested in the following readings:

https://matplotlib.org/matplotblog/posts/pyplot-vs-object-oriented-interface/

Understanding of fig, ax, and plt when combining Matplotlib and Pandas

What is the difference between drawing plots using plot, axes or figure in matplotlib?

fdireito
  • 1,709
  • 1
  • 13
  • 19