FishC 发表于 2026-2-22 18:39:02

kerln888 发表于 2026-02-22 18:38
@FishC matplotlib可以给子图添加悬停功能吗??

是的,Matplotlib可以通过事件处理给子图添加悬停功能。虽然Matplotlib本身没有内置的悬停组件,但我们可以利用mpl_connect方法绑定鼠标移动事件来实现类似效果。以下是一个简单示例,当鼠标悬停在子图的数据点上时,会显示该点的坐标信息:


import matplotlib.pyplot as plt
import numpy as np

# 创建图形和子图
fig, ax = plt.subplots()
x = np.arange(10)
y = np.random.rand(10)
points, = ax.plot(x, y, 'o')# 绘制散点图

# 初始化文本对象用于显示悬停信息
hover_text = ax.text(0, 0, '', backgroundcolor='yellow', alpha=0.7)

def on_hover(event):
    # 检查事件是否发生在当前子图内
    if event.inaxes == ax:
      # 计算鼠标位置与数据点的距离
      distances = np.sqrt((x - event.xdata)**2 + (y - event.ydata)**2)
      min_index = np.argmin(distances)
      min_distance = distances

      # 如果距离足够近,则显示悬停信息
      if min_distance < 0.5:# 阈值可根据需要调整
            hover_text.set_text(f'({x:.2f}, {y:.2f})')
            hover_text.set_position((x, y))
            fig.canvas.draw_idle()
      else:
            hover_text.set_text('')
            fig.canvas.draw_idle()

# 绑定鼠标移动事件
fig.canvas.mpl_connect('motion_notify_event', on_hover)

plt.show()


注意事项:
1. 上述代码使用motion_notify_event事件来检测鼠标移动,并通过计算鼠标与数据点的距离来触发悬停显示。
2. 悬停灵敏度通过距离阈值(示例中为0.5)控制,您可以根据实际情况调整。
3. 此方法适用于简单的悬停需求,对于复杂交互(如多子图或大量数据),可能需要更精细的事件处理或考虑使用其他库(如Plotly)。

如果需要为多个子图添加悬停功能,只需为每个子图单独绑定事件并处理相应的数据即可。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

kerln888 发表于 2026-2-22 23:44:31

@FishC 使用mplcursors对matplotlib增加悬停功能。柱状图x坐标是1,2,3。y轴坐标是1,2,3.如何实现鼠标移动到x轴0到1,y轴0-3这个区域,显示x坐标1的柱状信息

FishC 发表于 2026-2-22 23:45:24

kerln888 发表于 2026-02-22 23:44
@FishC 使用mplcursors对matplotlib增加悬停功能。柱 ...

要在鼠标移动到特定区域时显示柱状图信息,可以使用 mplcursors 实现。以下是一个完整的解决方案:


import matplotlib.pyplot as plt
import mplcursors
import numpy as np

# 创建数据
x =
y =
labels =

# 创建图形和坐标轴
fig, ax = plt.subplots()
bars = ax.bar(x, y, color='skyblue', edgecolor='black')

# 自定义悬停函数
def on_hover(sel):
    # 获取鼠标坐标(数据坐标)
    x_mouse, y_mouse = sel.target
   
    # 定义触发区域:x轴0到1,y轴0到3
    if 0 <= x_mouse <= 1 and 0 <= y_mouse <= 3:
      # 显示第一个柱子的信息(索引0对应x=1)
      sel.annotation.set_text(labels)
    else:
      # 其他区域正常显示对应柱子的信息
      index = sel.index
      sel.annotation.set_text(labels)

# 启用mplcursors
cursor = mplcursors.cursor(bars, hover=True)
cursor.connect("add", on_hover)

# 设置图形属性
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.set_title('带悬停功能的柱状图')
ax.set_xticks(x)

plt.show()


工作原理:
1. 创建柱状图,每个柱子有对应的标签信息
2. 定义自定义悬停函数 on_hover,检测鼠标位置
3. 当鼠标在x轴0-1、y轴0-3范围内时,显示第一个柱子的信息
4. 在其他区域时,正常显示对应柱子的信息

关键点说明:
- sel.target 获取鼠标在数据坐标系中的位置
- 通过条件判断确定鼠标是否在指定区域内
- 使用 labels 显示第一个柱子的信息(x=1对应的柱子)

如果只想在指定区域显示悬停,可以简化函数:


def on_hover(sel):
    x_mouse, y_mouse = sel.target
    if 0 <= x_mouse <= 1 and 0 <= y_mouse <= 3:
      sel.annotation.set_text(labels)
    else:
      sel.annotation.set_visible(False)# 隐藏悬停


这样配置后,当鼠标移动到x轴0-1、y轴0-3区域时,会自动显示第一个柱子的信息。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

kerln888 发表于 2026-2-22 23:52:26

@FishC matplotlib多柱状图,可以获取x轴和y轴的最大值吗?

FishC 发表于 2026-2-22 23:52:51

kerln888 发表于 2026-02-22 23:52
@FishC matplotlib多柱状图,可以获取x轴和y轴的最大 ...

可以获取。以下是具体方法:


import matplotlib.pyplot as plt
import numpy as np

# 示例数据
labels = ['A', 'B', 'C', 'D']# x轴标签(分类)
data1 =       # 第一组柱子高度
data2 =          # 第二组柱子高度
data3 =          # 第三组柱子高度

x = np.arange(len(labels))   # 柱子的x坐标
width = 0.25                   # 柱子的宽度

fig, ax = plt.subplots()
# 绘制多柱状图
rects1 = ax.bar(x - width, data1, width, label='组1')
rects2 = ax.bar(x, data2, width, label='组2')
rects3 = ax.bar(x + width, data3, width, label='组3')

# 获取y轴最大值(所有柱子中的最大高度)
all_heights = data1 + data2 + data3
y_max = max(all_heights)# 或者用 np.max(all_heights)
print(f"Y轴最大值 (数据): {y_max}")

# 获取x轴“最大值”的两种常见理解:

# 1. 如果你的x轴是数值型(例如 x = ),想要x坐标最大值:
if isinstance(x, np.ndarray):
    x_max_coord = x.max() + width * 2# 考虑到最右侧柱子的偏移
    print(f"X轴坐标最大值 (考虑多柱偏移): {x_max_coord}")

# 2. 更常见的情况:x轴是分类,我们关心有多少组(即刻度数量)
x_group_count = len(labels)
print(f"X轴分组数量: {x_group_count}")

# 你也可以直接从坐标轴对象获取当前范围
# 注意:这通常在绘制后调用,返回的是当前视图范围
xlim_current = ax.get_xlim()
ylim_current = ax.get_ylim()
print(f"当前X轴范围: {xlim_current}")
print(f"当前Y轴范围: {ylim_current}")

# 设置图表
ax.set_ylabel('Y值')
ax.set_xlabel('X分组')
ax.set_title('多柱状图示例')
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.legend()

plt.show()


关键点解释:
1.Y轴最大值:直接比较所有柱状图数据列表,找出最大值。
2.X轴“最大值”:
    *   对于分类轴,通常指分组数量 len(labels)。
    *   对于数值轴,可计算最大坐标值(需考虑多柱的偏移宽度)。
3.绘图后,可用 ax.get_xlim() 和 ax.get_ylim() 获取坐标轴当前显示范围。

这样就能灵活获取和控制图表边界了。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

kerln888 发表于 2026-2-22 23:57:47

@FishC 回到刚刚的问题。使用mplcursors对matplotlib增加悬停功能。柱状图x坐标不是数字1,2,3,而是苹果,香蕉,荔枝。y轴坐标是1%,2%,3%.如何实现鼠标移动到x轴0到苹果,y轴0-3%这个区域,显示x坐标苹果的柱状信息。移动到x轴苹果到香蕉,y轴0-3%这个区域,显示x坐标香蕉的柱状信息。移动到x轴香蕉到荔枝,y轴0-3%这个区域,显示x坐标荔枝的柱状信息。

FishC 发表于 2026-2-22 23:58:40

kerln888 发表于 2026-02-22 23:57
@FishC 回到刚刚的问题。使用mplcursors对matplotlib ...

要使用 mplcursors 实现柱状图的悬停功能,并按照指定区域显示对应分类的信息,可以按照以下步骤操作:

1. 创建柱状图时,直接使用分类数据(如苹果、香蕉、荔枝)作为 x 坐标,matplotlib 会自动处理。
2. 使用 mplcursors 绑定到柱状图对象,并设置悬停事件。
3. 在悬停事件中,通过索引获取对应的分类和数值,并显示在注解中。

以下是完整的代码示例:


import matplotlib.pyplot as plt
import mplcursors

# 数据准备
x_categories = ['苹果', '香蕉', '荔枝']
y_values = # 百分比数值

# 创建柱状图
fig, ax = plt.subplots()
bars = ax.bar(x_categories, y_values)

# 设置 y 轴标签和范围
ax.set_ylabel('百分比')
ax.set_ylim(0, max(y_values) + 1)

# 初始化 mplcursors,绑定到柱状图对象
cursor = mplcursors.cursor(bars, hover=True)

# 定义悬停时显示的信息
@cursor.connect("add")
def on_add(sel):
    # 获取当前柱子的索引
    index = sel.target.index
    # 根据索引获取分类和数值
    label = x_categories
    value = y_values
    # 设置注解文本
    sel.annotation.set_text(f"{label}: {value}%")

plt.show()


代码说明:
- x_categories 存储分类标签,y_values 存储对应的百分比数值。
- ax.bar() 直接使用分类数据创建柱状图,每个柱子对应一个分类。
- mplcursors 绑定到 bars 对象,当鼠标悬停在柱子上时触发事件。
- on_add 函数中,通过 sel.target.index 获取柱子索引,从而得到分类和数值,并设置注解文本。

运行此代码后,鼠标悬停在每个柱子上(即对应的 x 轴区域)时,会显示该柱子的分类和百分比信息。例如,悬停在第一个柱子上(对应 x 轴“苹果”区域)会显示“苹果: 1%”。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

kerln888 发表于 2026-2-23 00:20:00

@FishC matplotlib legend可以放在坐标外吗?比如放在坐标下面

FishC 发表于 2026-2-23 00:20:31

kerln888 发表于 2026-02-23 00:20
@FishC matplotlib legend可以放在坐标外吗?比如放在 ...

是的,Matplotlib 的图例可以放在坐标轴外部,比如坐标下面。你可以使用 bbox_to_anchor 参数来指定图例的位置。

示例代码:


import matplotlib.pyplot as plt

# 创建示例数据
x =
y1 =
y2 =

plt.plot(x, y1, label='Line 1')
plt.plot(x, y2, label='Line 2')

# 将图例放在坐标轴下方,居中
plt.legend(bbox_to_anchor=(0.5, -0.1), loc='upper center')

# 调整图形边界,确保图例显示完整
plt.subplots_adjust(bottom=0.2)

plt.show()


在这个例子中,bbox_to_anchor=(0.5, -0.1) 将图例定位在坐标轴下方(水平居中,y 坐标为负值表示在轴外),loc='upper center' 设置图例的锚点在图例的上方中心。使用 plt.subplots_adjust(bottom=0.2) 可以增加底部空间,防止图例被裁剪。你也可以尝试其他位置,比如将 bbox_to_anchor 设置为 (0, -0.1) 来左对齐,或者调整 loc 参数如 'lower center' 来微调。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

kerln888 发表于 2026-2-23 00:39:22

@FishC matplotlib子图的legend可以放在坐标外吗?ax1 = fig.add_subplot(gs),比如放在坐标下面

FishC 发表于 2026-2-23 00:39:49

kerln888 发表于 2026-02-23 00:39
@FishC matplotlib子图的legend可以放在坐标外吗?ax1 ...

可以,matplotlib 的子图图例可以通过 bbox_to_anchor 参数放置在坐标轴外部,例如坐标下方。以下是一个示例代码,展示如何实现:


import matplotlib.pyplot as plt

# 创建图形和网格子图
fig = plt.figure()
gs = fig.add_gridspec(1, 1)# 简单网格示例
ax1 = fig.add_subplot(gs)# 创建子图

# 绘制示例数据
ax1.plot(, , label='示例曲线')

# 添加图例,放置在坐标轴下方外部
# bbox_to_anchor 的 (0.5, -0.1) 表示在坐标轴中心下方(负值表示外部)
ax1.legend(loc='upper center', bbox_to_anchor=(0.5, -0.1), ncol=1)

# 调整布局以避免图例被裁剪
plt.tight_layout()

plt.show()


关键点:
- 使用 bbox_to_anchor 指定图例位置,例如 (0.5, -0.1) 将图例放在子图中心下方。
- loc='upper center' 设置图例锚点为子图上部中心,与 bbox_to_anchor 配合。
- plt.tight_layout() 自动调整布局,确保图例可见。

如果图例仍被裁剪,可手动调整子图位置,例如:

plt.subplots_adjust(bottom=0.2)# 为底部留出更多空间


此方法适用于任何子图,包括通过 add_subplot(gs[...]) 创建的。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

kerln888 发表于 2026-2-23 11:03:27

@FishC matplotlib的legend过长,可以分几列排列吗?

FishC 发表于 2026-2-23 11:03:51

kerln888 发表于 2026-02-23 11:03
@FishC matplotlib的legend过长,可以分几列排列吗?

是的,matplotlib的图例可以通过设置 ncol 参数来分列排列。这个参数指定了图例的列数,从而将过长的图例分成多行显示。

例如,如果你有多个图例项,可以这样设置:


import matplotlib.pyplot as plt

# 示例数据
x =
y1 =
y2 =
y3 =
y4 =

plt.plot(x, y1, label='Line 1')
plt.plot(x, y2, label='Line 2')
plt.plot(x, y3, label='Line 3')
plt.plot(x, y4, label='Line 4')

# 添加图例,设置分两列显示
plt.legend(ncol=2)

plt.show()


在这个例子中,ncol=2 会让图例分两列排列。你可以根据需要调整这个数字,比如 ncol=3 分三列。

如果图例项很多,分列排列可以有效避免图例过长影响图表美观。此外,你还可以结合其他参数(如 loc 调整位置)进一步优化图例显示。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

kerln888 发表于 2026-2-23 19:29:52

@FishC js,data-forge怎么对series去重?比如:
let dataFrame = new DataFrame([
            {
                A: 1,
                B: 10,
            },
            {
                A: 2,
                B: 20,
            },
         {
                A: 2,
                B: 30,
            }
      ]);
dataFrame.getSeries("A")怎么去重

FishC 发表于 2026-2-23 19:30:13

kerln888 发表于 2026-02-23 19:29
@FishC js,data-forge怎么对series去重?比如:
let ...

在 Data-Forge 中,可以使用 distinct() 方法对 Series 进行去重。该方法会返回一个新的 Series,包含原 Series 中的唯一值。

示例代码:


let dataFrame = new DataFrame([
    { A: 1, B: 10 },
    { A: 2, B: 20 },
    { A: 2, B: 30 }
]);

let seriesA = dataFrame.getSeries("A");
let uniqueSeries = seriesA.distinct();

console.log(uniqueSeries.toArray()); // 输出:


这样,uniqueSeries 就是去重后的 Series。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

kerln888 发表于 2026-2-23 20:33:48

@FishC
let dataFrame = new DataFrame([
    { A: 2021-06-26T03:45:00.000Z, B: 10 },
    { A: 2021-06-27T03:45:00.000Z, B: 20 },
    { A: 2021-06-28T03:45:00.000Z, B: 30 }
]);
使用Data-Forge,let seriesA = dataFrame.getSeries("A");seriesA如何只取年

FishC 发表于 2026-2-23 20:34:29

kerln888 发表于 2026-02-23 20:33
@FishC
let dataFrame = new DataFrame();
使用Dat ...

你好!要从系列 A 中只取年份,你可以使用 select 方法将每个日期值转换为年份。假设系列中的值是日期字符串,你需要先将它们转换为 Date 对象,然后提取年份。

以下是示例代码:


let dataFrame = new DataFrame([
    { A: '2021-06-26T03:45:00.000Z', B: 10 },
    { A: '2021-06-27T03:45:00.000Z', B: 20 },
    { A: '2021-06-28T03:45:00.000Z', B: 30 }
]);

let seriesA = dataFrame.getSeries("A");
let yearSeries = seriesA.select(value => new Date(value).getFullYear());

// 查看结果
console.log(yearSeries.toArray()); // 输出:


注意:在原始代码中,日期值没有引号,但在 JavaScript 中,如果直接写日期字符串,需要引号。所以我在代码中添加了引号。如果你的日期值已经是字符串或 Date 对象,请相应调整。

解释:

- 使用 getSeries 获取系列 A。
- 使用 select 方法对每个值应用一个函数,该函数将值转换为 Date 对象并调用 getFullYear() 获取年份。
- 结果是一个新系列 yearSeries,包含年份。

这样,你就只取了年份。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

kerln888 发表于 2026-2-23 23:09:41

@FishC
let dataFrame = new DataFrame([
    { A: '2021-06-26T03:45:00.000Z', B: 10, C:'香蕉', D:'猴子' },
    { A: '2021-06-27T03:45:00.000Z', B: 20, C:'香蕉', D:'狮子'},
    { A: '2022-06-28T03:45:00.000Z', B: 30, C:'苹果', D:'大象'},
   { A: '2021-07-28T03:45:00.000Z', B: 50, C:'苹果', D:'猴子'},
   { A: '2025-06-28T03:45:00.000Z', B: 60, C:'梨子', D:'狮子'},
   { A: '2021-09-28T03:45:00.000Z', B: 30, C:'橘子', D:'老虎'},
]);
使用Data-Forge,筛选出A in ,B in ,C in ['苹果', '梨子'] D in ['猴子', '狮子']。应该怎么做

FishC 发表于 2026-2-23 23:10:56

kerln888 发表于 2026-02-23 23:09
@FishC
let dataFrame = new DataFrame();
使用Data ...

要筛选满足多个条件的数据,可以使用 Data-Forge 的 where 方法,结合逻辑运算符组合条件。以下是对应的 JavaScript 代码:


const DataFrame = require('data-forge');

let dataFrame = new DataFrame([
    { A: '2021-06-26T03:45:00.000Z', B: 10, C:'香蕉', D:'猴子' },
    { A: '2021-06-27T03:45:00.000Z', B: 20, C:'香蕉', D:'狮子'},
    { A: '2022-06-28T03:45:00.000Z', B: 30, C:'苹果', D:'大象'},
    { A: '2021-07-28T03:45:00.000Z', B: 50, C:'苹果', D:'猴子'},
    { A: '2025-06-28T03:45:00.000Z', B: 60, C:'梨子', D:'狮子'},
    { A: '2021-09-28T03:45:00.000Z', B: 30, C:'橘子', D:'老虎'},
]);

// 提取年份并转换为数字
dataFrame = dataFrame.withSeries('Year',
    dataFrame.deflate(row => new Date(row.A).getFullYear()));

// 筛选条件
const filtered = dataFrame.where(row => {
    const year = row.Year;
    const bValue = row.B;
    const cValue = row.C;
    const dValue = row.D;

    return (.includes(year) &&
            .includes(bValue) &&
            ['苹果', '梨子'].includes(cValue) &&
            ['猴子', '狮子'].includes(dValue));
});

console.log(filtered.toString());


这段代码执行以下步骤:

1. 使用 withSeries 添加一个新列 "Year",提取日期列 A 的年份。
2. 在 where 方法中定义筛选条件,使用 includes 检查每个值是否在指定范围内。
3. 条件之间使用逻辑与 (&&) 连接,确保同时满足所有条件。

输出结果将只包含满足所有条件的行:
- A 列年份为 2021 或 2022
- B 列值为 30 或 50
- C 列值为 "苹果" 或 "梨子"
- D 列值为 "猴子" 或 "狮子"

如果不希望保留 "Year" 列,可以在筛选后使用 dropSeries('Year') 删除。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

kerln888 发表于 2026-2-23 23:16:33

@FishC
let dataFrame = new DataFrame([
    { A: '2021-06-26T03:45:00.000Z', B: 10, C:'香蕉', D:'猴子' },
    { A: '2021-06-27T03:45:00.000Z', B: 20, C:'香蕉', D:'狮子'},
    { A: '2022-06-28T03:45:00.000Z', B: 30, C:'苹果', D:'大象'},
   { A: '2021-07-28T03:45:00.000Z', B: 50, C:'苹果', D:'猴子'},
   { A: '2025-06-28T03:45:00.000Z', B: 60, C:'梨子', D:'狮子'},
   { A: '2021-09-28T03:45:00.000Z', B: 30, C:'橘子', D:'老虎'},
]);
使用Data-Forge,筛选出A in ,A in ,C in ['苹果', '梨子'] D in ['猴子', '狮子']。应该怎么做
页: 17 18 19 20 21 22 23 24 25 26 [27] 28 29 30 31 32 33 34
查看完整版本: html5 左边菜单栏保持展开或者关闭的状态