如何在多个散点之间放置箭头

How to place arrows between multiple scatter points

下面的代码生成了这张图。想知道有没有办法把value1和value2之间的线做成箭头,指向1到2的方向,从蓝色到绿色(在这种情况下none蓝色比绿色低)

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
 
# Create a dataframe
value1=np.random.uniform(size=20)
value2=value1+np.random.uniform(size=20)/4
df = pd.DataFrame({'group':list(map(chr, range(65, 85))), 'value1':value1 , 'value2':value2 })
 
# Reorder it following the values of the first value:
ordered_df = df.sort_values(by='value1')
my_range=range(1,len(df.index)+1)
 
# The horizontal plot is made using the hline function
plt.hlines(y=my_range, xmin=ordered_df['value1'], xmax=ordered_df['value2'], color='grey', alpha=0.4)
plt.scatter(ordered_df['value1'], my_range, color='skyblue', alpha=1, label='value1')
plt.scatter(ordered_df['value2'], my_range, color='green', alpha=0.4 , label='value2')
plt.legend()
 
# Add title and axis names
plt.yticks(my_range, ordered_df['group'])
plt.title("Comparison of the value 1 and the value 2", loc='left')
plt.xlabel('Value of the variables')
plt.ylabel('Group')

# Show the graph
plt.show()

您可以使用 plt.arrow 而不是 plt.hlines,但您必须循环遍历以下行:

for y, (_, row) in enumerate(ordered_df.iterrows()):
    arrow_head_length = 0.02
    plt.arrow(x=row['value1'], y=y+1, dx=row['value2']-row['value1']-arrow_head_length, dy=0,
              head_width=0.5, head_length=arrow_head_length, fc='k', ec='k',
              color='grey', alpha=0.4)

示例:

  • 多箭头的最佳选择是matplotlib.pyplot.quiver, because it accepts an array or dataframe of locations, unlike matplotlib.pyplot.arrow,它只接受一个值。
    • 由于 y 轴标签由 'group' 定义,它们是字母,因此使用 V = np.zeros(len(ordered_df))V = ordered_df.index - ordered_df.index 作为 .quiver 方向向量。
  • 直接使用 pandas.DataFrame.plotkind='scatter' 绘制数据帧。
  • 测试于 python 3.8.12pandas 1.3.3matplotlib 3.4.3
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Create a dataframe
np.random.seed(354)
value1=np.random.uniform(size=20)
value2=value1+np.random.uniform(size=20)/4
df = pd.DataFrame({'group':list(map(chr, range(65, 85))), 'value1':value1 , 'value2':value2 })
 
# Reorder it following the values of the first value and reset the index so the index values correspond to the y-axis tick locations
ordered_df = df.sort_values(by='value1').reset_index(drop=True)

# plot the dataframe
ax = ordered_df.plot(kind='scatter', x='value1', y='group', color='skyblue', alpha=1, figsize=(8, 6), label='value1')
ordered_df.plot(kind='scatter', x='value2', y='group', color='green', alpha=1, ax=ax, label='value2', xlabel='Value of the variables', ylabel='Group')

# plot the arrows
V = ordered_df.index - ordered_df.index  # the Y direction vector is 0 for each
ax.quiver(ordered_df.value1, ordered_df.group, (ordered_df.value2-ordered_df.value1), V, width=0.003, color='gray', scale_units='x', scale=1)

# Add title with position
ax.set_title("Comparison of the value 1 and the value 2", loc='left')

# Show the graph
plt.show()