You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Matplotlib中创建多平行线自定义线型以划分地质剖面?

问题描述

我正在绘制用于划分两个地质剖面的图表,希望使用三条平行虚线作为划分标识。但不清楚如何在Matplotlib中创建由多条线组成的线型,目前通过偏移三组数组的方式实现该效果,虽然呈现效果尚可,但编程过程繁琐,且在部分图表中线型对齐效果很差。请问是否存在由多条线构成的自定义线型方案?

当前实现代码:

import numpy as np
import matplotlib.pyplot as plt

fs = 12  # 补充原代码缺失的字体大小定义
Pd=np.array([17.5,22.5,27.5,27.5,42.5,47.5,47.5,52.5,52.5,37.5,32.5,47.5,32.5,0,22.5,0])
Px=np.array([23.6685,23.681,23.6935,23.706,23.7185,23.731,23.7435,23.756,23.7685,23.781,23.7935,23.806,23.8185,23.831,23.8435,23.856])
Pd1=np.array([23.5,28.5,28.5,43.5,49.5,49.5,54.5,54.5,38.5,34.5,49.5,32.5,3,25.5,0])
Px1=np.array([23.681,23.6919,23.7044,23.7169,23.7294,23.7419,23.7544,23.7701,23.7826,23.7935,23.806,23.8201,23.831,23.8435,23.8576])
Pd2=np.array([21.5,26.5,26.5,41.5,45.5,45.5,50.5,50.5,35.5,29.5,45.5,32.5,-3,19.5,0])
Px2=np.array([23.681,23.6951,23.7076,23.7201,23.7326,23.7451,23.7576,23.7669,23.7794,23.7935,23.806,23.8169,23.831,23.8435,23.8544])

fig,ax=plt.subplots()
fig.set_size_inches(8,5)
ax.plot(Px,Pd,linestyle=(0,(10,5)),color='dimgray')
ax.plot(Px1,Pd1,linestyle=(0,(10,5)),color='dimgray')
ax.plot(Px2,Pd2,linestyle=(0,(10,5)),color='dimgray')
ax.xaxis.set_ticks_position('top') 
ax.set_ylim(150,0)
ax.set_xlim(23.88,23.7125)
ax.set_xlabel(u'Latitude \N{DEGREE SIGN}N',fontsize=fs)
ax.xaxis.set_label_position('top')
ax.set_ylabel('Depth (m)')
plt.show()

解决方案

方法1:使用路径效果(Path Effects)生成平行多线

无需手动偏移数组,仅绘制一条基础线,通过patheffects添加偏移的平行路径,自动保证线型完全对齐,代码更简洁:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patheffects as path_effects

fs = 12
Pd=np.array([17.5,22.5,27.5,27.5,42.5,47.5,47.5,52.5,52.5,37.5,32.5,47.5,32.5,0,22.5,0])
Px=np.array([23.6685,23.681,23.6935,23.706,23.7185,23.731,23.7435,23.756,23.7685,23.781,23.7935,23.806,23.8185,23.831,23.8435,23.856])

fig,ax=plt.subplots()
fig.set_size_inches(8,5)

# 绘制基础虚线,添加路径效果生成两条平行偏移线
line = ax.plot(Px, Pd, linestyle=(0,(10,5)), color='dimgray')[0]
# 设置像素偏移量(可根据需求调整)
offsets = [3, -3]
for offset in offsets:
    line.set_path_effects([
        path_effects.Stroke(offset=(offset, 0), foreground='dimgray'),
        path_effects.Normal()  # 保留原线条
    ])

ax.xaxis.set_ticks_position('top') 
ax.set_ylim(150,0)
ax.set_xlim(23.88,23.7125)
ax.set_xlabel(u'Latitude \N{DEGREE SIGN}N',fontsize=fs)
ax.xaxis.set_label_position('top')
ax.set_ylabel('Depth (m)')
plt.show()

若需基于数据坐标偏移,可通过ax.transData将数据域偏移量转换为像素偏移。

方法2:使用LineCollection批量绘制平行线条

将三条线的坐标打包成集合,统一设置线型,确保所有线条的虚线样式完全同步,避免手动偏移时的对齐问题:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection

fs = 12
Pd=np.array([17.5,22.5,27.5,27.5,42.5,47.5,47.5,52.5,52.5,37.5,32.5,47.5,32.5,0,22.5,0])
Px=np.array([23.6685,23.681,23.6935,23.706,23.7185,23.731,23.7435,23.756,23.7685,23.781,23.7935,23.806,23.8185,23.831,23.8435,23.856])

# 定义数据坐标偏移量(按需调整)
x_offsets = [0, 0.002, -0.002]
# 生成三条线的坐标集合
lines = []
for offset in x_offsets:
    lines.append(np.column_stack((Px + offset, Pd)))

fig,ax=plt.subplots()
fig.set_size_inches(8,5)

# 创建LineCollection,统一设置线型和颜色
lc = LineCollection(lines, linestyle=(0,(10,5)), color='dimgray')
ax.add_collection(lc)

ax.xaxis.set_ticks_position('top') 
ax.set_ylim(150,0)
ax.set_xlim(23.88,23.7125)
ax.set_xlabel(u'Latitude \N{DEGREE SIGN}N',fontsize=fs)
ax.xaxis.set_label_position('top')
ax.set_ylabel('Depth (m)')
plt.show()

方法3:改进手动偏移的对齐问题

若坚持使用多数组偏移方式,可通过统一计算偏移量、同步线型相位解决对齐问题:

import numpy as np
import matplotlib.pyplot as plt

fs = 12
Pd=np.array([17.5,22.5,27.5,27.5,42.5,47.5,47.5,52.5,52.5,37.5,32.5,47.5,32.5,0,22.5,0])
Px=np.array([23.6685,23.681,23.6935,23.706,23.7185,23.731,23.7435,23.756,23.7685,23.781,23.7935,23.806,23.8185,23.831,23.8435,23.856])

# 统一计算偏移量,避免手动输入误差
offset = 0.002
Px1 = Px + offset
Px2 = Px - offset
Pd1 = Pd
Pd2 = Pd

fig,ax=plt.subplots()
fig.set_size_inches(8,5)

# 使用相同的线型定义,确保虚线相位一致
dash_style = (0, (10,5))
ax.plot(Px,Pd,linestyle=dash_style,color='dimgray')
ax.plot(Px1,Pd1,linestyle=dash_style,color='dimgray')
ax.plot(Px2,Pd2,linestyle=dash_style,color='dimgray')

ax.xaxis.set_ticks_position('top') 
ax.set_ylim(150,0)
ax.set_xlim(23.88,23.7125)
ax.set_xlabel(u'Latitude \N{DEGREE SIGN}N',fontsize=fs)
ax.xaxis.set_label_position('top')
ax.set_ylabel('Depth (m)')
plt.show()

内容的提问来源于stack exchange,提问作者BrianM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 17:20:36