我正在使用Matplotlib创建一个图。我希望图例键(图例中描述性文本旁边的形状)是类似于图中的箭头。我已经能够得到一个输出,这是接近我想要的,你可以看到在下面的图片。传说中有箭,但它们又长又窄。
The current iteration of my plot. The legend key arrows are present but tiny.
我用来创建图的代码如下:
# Define custom legend handler
class ArrowHandler(HandlerBase):
def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans):
arrow = FancyArrowPatch((0, 5), (40, 5), arrowstyle='->', color=orig_handle.get_edgecolor(), mutation_aspect=20)
return [arrow]
# Plot the river profile using Matplotlib
plt.figure(figsize=(11, 6))
plt.plot(creek_long_profile_dataframes['Foley Creek']['distance_upstream_km'],
creek_long_profile_dataframes['Foley Creek']['elevation_m'],
color='#368bb5', linewidth=2)
### Add sediment delivery points as colored arrows
delivery_data = creek_sed_delivery_dataframes["Foley Creek"]
# Get range of x and y values to be able to standardize the size of the arrows
x_min_max = creek_long_profile_dataframes['Foley Creek']['distance_upstream_km'].agg(['min', 'max'])
x_range = x_min_max[1] - x_min_max[0]
y_min_max = creek_long_profile_dataframes['Foley Creek']['elevation_m'].agg(['min', 'max'])
y_range = y_min_max[1] - y_min_max[0]
# Add arrows to the figure
for index, row in delivery_data.iterrows():
x = row['distance_upstream_km']
y = row['elevation_m']
color = '#1b9e77' if row['mass_movement_type'] == 'Debris Flow' else '#7570b3'
plt.arrow(x, y+(0.098*y_range), 0, -(0.088*y_range), width=0.006*x_range, head_width=0.015*x_range,
head_length=0.029*y_range, color=color, length_includes_head=True)
### done adding sediment delivery arrows
# Set axis labels
plt.xlabel('Distance upstream (km)')
plt.ylabel('Elevation (m)')
# Set title
plt.title('Sediment Delivery Along Foley Creek')
# Add grid
plt.grid(which='major', axis='both')
# Define the legend elements
legend_elements = [
FancyArrowPatch((0, 0), (0, 0), arrowstyle='->', color='#1b9e77', label='Debris Flow'),
FancyArrowPatch((0, 0), (0, 0), arrowstyle='->', color='#7570b3', label='Debris Avalanche')
]
# Create the legend with custom handler
plt.legend(handles=legend_elements, handler_map={FancyArrowPatch: ArrowHandler()})
# Save figure
# plt.savefig('sed_delivery_figs/sed_delivery_foley.pdf', dpi=300, bbox_inches='tight')
# Show the plot
plt.show()
我首先尝试传递一个类似于下面代码的Arrow示例列表。
# Define the legend elements
legend_elements = [
FancyArrowPatch((0, 0), (0.5, 0), arrowstyle='->', color='#1b9e77', label='Debris Flow'),
FancyArrowPatch((0, 0), (0.5, 0), arrowstyle='->', color='#7570b3', label='Debris Avalanche')
]
# Add the legend
plt(handles=legend_elements, loc='center')
这导致图例键是矩形的(不是我希望的箭头),但颜色是正确的。
我蹒跚地一起创建一个自定义的图例处理程序的一些代码,但不幸的是,我很少了解他们如何工作,我应该如何定义它。任何帮助将不胜感激。
我已经看了一些相关的文章(here和here),但是我还没有能够在我的用例中实现他们的建议,因为我在Matplotlib的某些方面遇到了麻烦。
有谁知道我怎样才能把箭头的传说一样,我绘制的数字本身?有没有更简单的方法?
1条答案
按热度按时间jq6vz3qz1#
很好地提出了你的问题,并提供了相关的支持细节。
我不能说我明白这一切是如何运作的。但是我可以说使用FancyArrow(来自matplotlib.patches)而不是FancyArrowPatch对我来说是有效的。你能试试这样的吗?
希望你能在你的传说中得到清晰可辨的箭头形状的箭头。(我的想法来自https://matplotlib.org/stable/gallery/shapes_and_collections/arrow_guide.html)