FishC 发表于 2026-2-18 17:29:45

kerln888 发表于 2026-02-18 17:29
@FishC javasript Plotly.js如何创建子图

在 Plotly.js 中创建子图,通常使用 make_subplots 函数。以下是具体步骤:


[*]引入 Plotly.js 库和 make_subplots 函数。

<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script>
    // 代码将写在这里
</script>


[*]使用 Plotly.makeSubplots 创建子图网格。

// 创建一个 2x2 的子图网格
var fig = {
    data: [],
    layout: {},
    config: {responsive: true}
};

Plotly.makeSubplots({
    rows: 2,
    cols: 2,
    subplotTitles: ['子图 1', '子图 2', '子图 3', '子图 4']
}).then(function(figure) {
    fig = figure;
   
    // 添加数据到每个子图
    // 示例:为每个子图添加散点图
    for (var i = 0; i < 4; i++) {
      fig.addTrace({
            x: ,
            y: ,
            type: 'scatter',
            mode: 'lines+markers',
            name: '数据系列 ' + (i + 1)
      }, Math.floor(i / 2) + 1, (i % 2) + 1); // 指定行和列
    }
   
    // 绘制图表到指定的 div 元素
    Plotly.newPlot('myDiv', fig.data, fig.layout, fig.config);
});


[*]在 HTML 中添加一个容器 div。

<div id="myDiv" style="width: 800px; height: 600px;"></div>



关键点:

[*]使用 Plotly.makeSubplots 创建网格布局。
[*]使用 addTrace 方法添加数据到指定位置(行和列从 1 开始计数)。
[*]子图类型可以是散点图、折线图、柱状图等,通过 type 参数设置。


提示:

[*]确保 Plotly.js 库已正确加载。
[*]调整 rows 和 cols 参数可以改变子图数量。
[*]使用 subplotTitles 为每个子图添加标题。


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

kerln888 发表于 2026-2-18 17:33:10

FishC 发表于 2026-2-18 17:29
[*]引入 Plotly.js 库和 make_subplots 函数。




@FishC javasript中使用make_subplots函数,而不是makeSubplots!!请写出正确的例子

FishC 发表于 2026-2-18 17:33:35

kerln888 发表于 2026-02-18 17:33
FishC 发表于 2026-2-18 17:29
引入 Plotly.js 库和...

在 JavaScript 的 Plotly.js 库中,创建子图的正确函数是 Plotly.makeSubplots(驼峰命名法),而不是 make_subplots。以下是一个使用该函数的示例:

// 引入 Plotly.js 库后,使用 Plotly.makeSubplots 创建子图
// 假设已通过 CDN 等方式引入 Plotly.js

// 定义两个轨迹数据
var trace1 = {
x: ,
y: ,
type: 'scatter',
name: '散点图'
};

var trace2 = {
x: ,
y: ,
type: 'bar',
name: '柱状图'
};

// 使用 Plotly.makeSubplots 创建子图布局(2 行 1 列)
Plotly.makeSubplots({
rows: 2,
cols: 1,
subplotTitles: ['子图1: 散点图', '子图2: 柱状图']
}).then(function(fig) {
// 将轨迹添加到子图的指定位置
fig.addTrace(trace1, 1, 1); // 第一行第一列
fig.addTrace(trace2, 2, 1); // 第二行第一列

// 在页面中绘制图表,假设有一个 id 为 'myDiv' 的容器
Plotly.newPlot('myDiv', fig.data, fig.layout);
});

注意:确保在 HTML 中有一个 <div id="myDiv"></div> 元素来显示图表。此示例展示了如何创建包含散点图和柱状图的子图。

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

kerln888 发表于 2026-2-18 17:36:11

FishC 发表于 2026-2-18 17:33
在 JavaScript 的 Plotly.js 库中,创建子图的正确函数是 Plotly.makeSubplots(驼峰命名法),而不是...

@FishC 报错了,Uncaught TypeError: Plotly.makeSubplots is not a function

FishC 发表于 2026-2-18 17:36:37

kerln888 发表于 2026-02-18 17:36
FishC 发表于 2026-2-18 17:33
在 JavaScript 的 Plo ...

嗨,遇到这个错误,通常是因为函数名写错了或者Plotly.js的版本不对。

请按以下步骤检查和解决:

1.**检查函数名拼写是否正确(最重要的步骤)**
    正确的大小写是:Plotly.makeSubplots。
    请仔细核对你的代码,确保没有写成 `makeSubplots`、`Makesubplots` 或其他变体。

2.**检查并更新你的 Plotly.js 版本**
    makeSubplots 函数是在相对较新的版本中引入的。如果你的版本太旧,这个函数就不存在。
    *   **推荐方法**:直接使用官方CDN链接引入一个较新的版本(例如 1.x.x 或 2.x.x)。
    *   在你HTML文件的 `<head>` 或 `<body>` 末尾,将旧的Plotly引用替换为:
      
      <script src="https://cdn.plot.ly/plotly-2.18.2.min.js"></script>
      

3.**如果更新版本后问题依旧,请使用以下正确代码示例进行测试**
    这是一个最基本的使用方法:
   
    // 1. 定义子图的网格布局
    var layout = {
      grid: {
            rows: 2,
            columns: 1,
            pattern: 'independent' // 子图使用独立的坐标轴
      },
      title: '使用 makeSubplots 创建的示例'
    };

    // 2. 定义两个简单的数据轨迹
    var trace1 = {
      x: ,
      y: ,
      type: 'scatter',
      name: '图表 A'
    };
    var trace2 = {
      x: ,
      y: ,
      type: 'scatter',
      name: '图表 B',
      xaxis: 'x2', // 指定使用第二套X轴
      yaxis: 'y2'// 指定使用第二套Y轴
    };

    var data = ;

    // 3. 创建图表!注意函数名:Plotly.makeSubplots
    Plotly.makeSubplots({
      rows: 2,
      cols: 1,
      specs: [ [{}, {}] ] // 为每个子图指定配置,这里两个都使用默认{}
    })
    .then(function(fig) { // makeSubplots 返回一个 Promise
      // fig 是一个包含了布局和初始数据的对象
      // 将我们的数据添加到对应的子图位置
      fig.addTraces(trace1, 1, 1); // 第一行,第一列
      fig.addTraces(trace2, 2, 1); // 第二行,第一列

      // 应用我们自定义的布局(包含 grid 配置)
      fig.layout = layout;

      // 渲染图表到指定的 div 元素
      Plotly.newPlot('myDiv', fig.data, fig.layout);
    });
   
    对应的HTML需要一个id为 `myDiv` 的元素:
   
    <div id="myDiv"></div>
   

**总结一下,请这样做:**

*   第一步:检查并修正代码中的函数名拼写。
*   第二步:将你的 Plotly.js 库链接更新到最新或较新的版本。
*   第三步:用上面的完整示例代码替换你的代码,测试是否能正常运行。

如果按照以上步骤操作后问题仍然存在,请告诉我你使用的Plotly.js具体版本号,我们再进一步排查。

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

kerln888 发表于 2026-2-19 00:44:20

@FishC 下载了plotly-3.3.0.min.js,nodejs 如何在前端html引入这个库

FishC 发表于 2026-2-19 00:44:52

kerln888 发表于 2026-02-19 00:44
@FishC 下载了plotly-3.3.0.min.js,nodejs 如何在前 ...

首先,将下载的 plotly-3.3.0.min.js 文件放在你的项目文件夹中,例如 js 目录下。然后,在前端 HTML 文件中使用 <script> 标签引入这个本地文件。

示例 HTML 代码:


<!DOCTYPE html>
<html>
<head>
    <title>Plotly 示例</title>
</head>
<body>
    <div id="chart"></div>

    <!-- 引入本地 Plotly 库 -->
    <script src="js/plotly-3.3.0.min.js"></script>
    <script>
      // 使用 Plotly 绘制图表
      var data = [{
            x: ,
            y: ,
            type: 'scatter'
      }];
      Plotly.newPlot('chart', data);
    </script>
</body>
</html>


注意:src 中的路径要正确对应文件位置。如果文件在 HTML 同级目录,直接写 plotly-3.3.0.min.js;如果在子目录如 js 中,则写 js/plotly-3.3.0.min.js。

如果你使用 Node.js 作为后端服务器,可能需要配置静态文件服务,以确保浏览器能访问到该 JS 文件。例如,使用 Express 框架时:


const express = require('express');
const app = express();
const path = require('path');

// 设置静态文件目录(假设文件放在 public/js/ 中)
app.use(express.static(path.join(__dirname, 'public')));

app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

app.listen(3000, () => {
    console.log('服务器已启动:http://localhost:3000');
});


将 plotly-3.3.0.min.js 放入 public/js/ 文件夹,并在 HTML 中将 src 改为 /js/plotly-3.3.0.min.js。这样,前端就能成功引入 Plotly 库了。

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

kerln888 发表于 2026-2-19 21:20:11

@FishC matplotlib创建了2*2的子图,能否实现点击任意子图,点击的子图放大占满整个画布,其他子图隐藏。再点击子图缩小到原来大小,显示其他子图,布局和点击之前一样

FishC 发表于 2026-2-19 21:20:55

kerln888 发表于 2026-02-19 21:20
@FishC matplotlib创建了2*2的子图,能否实现点击任意 ...

我们可以通过以下步骤实现这个交互功能:

1. 创建2x2的子图,并存储每个子图的原始位置信息
2. 为每个子图添加点击事件监听器
3. 在点击事件中切换子图的放大/缩小状态

下面是完整的实现代码:

import matplotlib.pyplot as plt
import numpy as np

# 创建2x2的子图
fig, axes = plt.subplots(2, 2, figsize=(8, 6))
fig.subplots_adjust(wspace=0.3, hspace=0.3)# 调整子图间距

# 存储每个子图的原始位置和状态
original_positions = {}
is_zoomed = False
current_zoomed_ax = None

# 为每个子图创建示例数据
titles = ['Subplot 1', 'Subplot 2', 'Subplot 3', 'Subplot 4']
for i, ax in enumerate(axes.flat):
    x = np.linspace(0, 2*np.pi, 100)
    y = np.sin(x + i*np.pi/4)
    ax.plot(x, y)
    ax.set_title(titles)
    ax.grid(True)
   
    # 存储原始位置
    original_positions = ax.get_position()

# 点击事件处理函数
def on_click(event):
    global is_zoomed, current_zoomed_ax
   
    # 检查点击是否发生在某个子图内
    for ax in axes.flat:
      if ax.contains(event):
            if not is_zoomed:
                # 放大点击的子图
                zoom_ax(ax)
                is_zoomed = True
                current_zoomed_ax = ax
            elif current_zoomed_ax == ax:
                # 如果点击的是已经放大的子图,则恢复
                restore_all()
                is_zoomed = False
                current_zoomed_ax = None
            else:
                # 如果已经有放大的子图,先恢复再放大新点击的子图
                restore_all()
                zoom_ax(ax)
                current_zoomed_ax = ax
            plt.draw()
            break

# 放大指定子图
def zoom_ax(ax):
    # 隐藏所有子图
    for a in axes.flat:
      a.set_visible(False)
   
    # 显示并放大选中的子图
    ax.set_visible(True)
    ax.set_position()# 设置到画布中央
    ax.set_title(f'{ax.get_title()} (Zoomed)', fontsize=14, fontweight='bold')

# 恢复所有子图到原始状态
def restore_all():
    for ax in axes.flat:
      ax.set_visible(True)
      ax.set_position(original_positions)
      # 恢复原始标题(去掉Zoomed标记)
      original_title = ax.get_title().replace(' (Zoomed)', '')
      ax.set_title(original_title)

# 连接点击事件
fig.canvas.mpl_connect('button_press_event', on_click)

plt.show()

代码说明:

1. original_positions:字典,存储每个子图的原始位置
2. is_zoomed:布尔值,记录当前是否有子图被放大
3. current_zoomed_ax:记录当前被放大的子图对象

主要函数:
- on_click():处理点击事件
- zoom_ax():放大指定子图,隐藏其他子图
- restore_all():恢复所有子图到原始状态

使用方式:
1. 运行代码后,点击任意子图,该子图会放大并占满画布
2. 再次点击放大的子图,会恢复到原来的2x2布局
3. 如果已经有放大的子图,点击其他子图会先恢复再放大新点击的子图

注意事项:
- 确保安装了最新版本的matplotlib
- 代码中的坐标轴位置参数可以根据需要调整
- 可以根据需要修改子图的大小和间距

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

kerln888 发表于 2026-2-19 22:22:22

@FishC
fig = Figure(figsize=(19.2, 10.8), dpi=100)
fig.subplots_adjust(left=0.1, right=0.9, top=0.95, bottom=0.05)
gs = gridspec.GridSpec(nrows=2, ncols=3)
ax1 = self.fig.add_subplot(gs)
ax2 = self.fig.add_subplot(gs)
ax3 = self.fig.add_subplot(gs)
ax4 = self.fig.add_subplot(gs)
ax5_6 = self.fig.add_subplot(gs)
matplotlib这样创建的子图,能否实现点击任意子图,点击的子图放大占满整个画布,其他子图隐藏。再点击子图缩小到原来大小,显示其他子图,布局和点击之前一样

FishC 发表于 2026-2-19 22:23:04

kerln888 发表于 2026-02-19 22:22
@FishC
fig = Figure(figsize=(19.2, 10.8), dpi=100 ...

要实现点击子图放大/缩小的交互功能,需要使用 matplotlib 的事件处理系统。以下是完整的解决方案:


import matplotlib.pyplot as plt
from matplotlib import gridspec
import matplotlib

class InteractiveSubplots:
    def __init__(self):
      self.fig = plt.figure(figsize=(19.2, 10.8), dpi=100)
      self.fig.subplots_adjust(left=0.1, right=0.9, top=0.95, bottom=0.05)
      gs = gridspec.GridSpec(nrows=2, ncols=3)
      
      # 创建子图
      self.ax1 = self.fig.add_subplot(gs)
      self.ax2 = self.fig.add_subplot(gs)
      self.ax3 = self.fig.add_subplot(gs)
      self.ax4 = self.fig.add_subplot(gs)
      self.ax5_6 = self.fig.add_subplot(gs)
      
      # 保存所有子图
      self.all_axes =
      
      # 保存原始位置信息
      self.original_positions = {}
      for ax in self.all_axes:
            self.original_positions = ax.get_position()
      
      # 当前放大的子图
      self.zoomed_ax = None
      
      # 绑定点击事件
      for ax in self.all_axes:
            ax._zoom_id = self.fig.canvas.mpl_connect('button_press_event',
                                                    lambda event, ax=ax: self.on_click(event, ax))
      
      # 为每个子图添加示例内容以便区分
      for i, ax in enumerate(self.all_axes, 1):
            ax.text(0.5, 0.5, f'Subplot {i}', ha='center', va='center', fontsize=20)
            ax.set_title(f'Ax{i}')
      
    def on_click(self, event, ax):
      if event.inaxes != ax:
            return
      
      if self.zoomed_ax is None:
            # 放大选中的子图
            self.zoomed_ax = ax
            
            # 隐藏其他子图
            for other_ax in self.all_axes:
                if other_ax != ax:
                  other_ax.set_visible(False)
            
            # 将选中的子图调整到整个画布
            ax.set_position()
            ax.set_title(f'{ax.get_title()} (Full Screen) - Click to return', fontsize=16)
            
      elif self.zoomed_ax == ax:
            # 恢复原始布局
            ax.set_position(self.original_positions)
            ax.set_title(ax.get_title().replace(' (Full Screen) - Click to return', ''))
            
            # 显示所有子图
            for other_ax in self.all_axes:
                other_ax.set_visible(True)
            
            self.zoomed_ax = None
      
      # 重绘画布
      self.fig.canvas.draw_idle()

# 使用示例
if __name__ == "__main__":
    interactive = InteractiveSubplots()
    plt.show()


关键点说明:

1. get_position() 和 set_position():用于保存和恢复子图的原始位置
2. set_visible(False/True):控制子图的显示/隐藏
3. mpl_connect('button_press_event', ...):绑定点击事件处理函数
4. event.inaxes:判断点击事件发生在哪个坐标轴内
5. fig.canvas.draw_idle():更新画布显示

注意事项:

1. 点击子图时会将其放大到整个画布,其他子图隐藏
2. 再次点击已放大的子图会恢复到原始布局
3. 点击画布空白区域不会触发任何操作
4. 确保安装了最新版本的 matplotlib:pip install matplotlib --upgrade

扩展建议:

1. 可以添加动画效果让过渡更平滑
2. 可以添加键盘快捷键支持(如按ESC键返回)
3. 可以保存更多状态信息(如坐标轴范围)以便完全恢复

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

kerln888 发表于 2026-2-19 23:01:31

@FishC
fig = Figure(figsize=(19.2, 10.8), dpi=100)
fig.subplots_adjust(left=0.1, right=0.9, top=0.95, bottom=0.05)
gs = gridspec.GridSpec(nrows=2, ncols=3)
ax1 = self.fig.add_subplot(gs)
ax2 = self.fig.add_subplot(gs)
ax3 = self.fig.add_subplot(gs)
ax3r = ax3.twinx()
ax4 = self.fig.add_subplot(gs)
ax5_6 = self.fig.add_subplot(gs)
matplotlib这样创建的子图,其中ax3子图中创建一个共享 x 轴但具有独立 y 轴的双 y 轴图表ax3r,能否实现点击任意子图,点击的子图放大占满整个画布,其他子图隐藏。再点击子图缩小到原来大小,显示其他子图,布局和点击之前一样

FishC 发表于 2026-2-19 23:02:58

kerln888 发表于 2026-02-19 23:01
@FishC
fig = Figure(figsize=(19.2, 10.8), dpi=100 ...

可以的,需要给子图添加事件监听器来实现这个功能。以下是完整的实现代码:


import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

class InteractiveFigure:
    def __init__(self):
      self.fig = plt.figure(figsize=(19.2, 10.8), dpi=100)
      self.fig.subplots_adjust(left=0.1, right=0.9, top=0.95, bottom=0.05)
      
      # 创建原始网格布局
      self.gs = gridspec.GridSpec(nrows=2, ncols=3)
      self.ax1 = self.fig.add_subplot(self.gs)
      self.ax2 = self.fig.add_subplot(self.gs)
      self.ax3 = self.fig.add_subplot(self.gs)
      self.ax3r = self.ax3.twinx()
      self.ax4 = self.fig.add_subplot(self.gs)
      self.ax5_6 = self.fig.add_subplot(self.gs)
      
      # 保存原始布局信息
      self.original_layout = {
            'fig': {'left': 0.1, 'right': 0.9, 'top': 0.95, 'bottom': 0.05},
            'grid': self.gs,
            'axes':
      }
      
      self.is_zoomed = False# 标记是否处于放大状态
      self.current_zoomed_axes = None# 当前被放大的坐标轴
      
      # 绑定点击事件到所有坐标轴
      self.bind_click_events()
      
    def bind_click_events(self):
      """为所有坐标轴绑定点击事件"""
      for ax in self.original_layout['axes']:
            # 跳过双Y轴中的第二个Y轴,避免重复处理
            if ax is not self.ax3r:
                ax.figure.canvas.mpl_connect('button_press_event',
                                           lambda event, ax=ax: self.on_click(event, ax))
      
    def on_click(self, event, ax):
      """点击事件处理函数"""
      if event.inaxes != ax:
            return
            
      if not self.is_zoomed:
            self.zoom_axes(ax)
      else:
            self.restore_layout()
   
    def zoom_axes(self, ax):
      """放大指定坐标轴"""
      # 隐藏所有其他坐标轴
      for other_ax in self.original_layout['axes']:
            other_ax.set_visible(False)
      
      # 显示点击的坐标轴及其相关坐标轴(针对双Y轴)
      if ax in :
            self.ax3.set_visible(True)
            self.ax3r.set_visible(True)
      else:
            ax.set_visible(True)
      
      # 调整布局:点击的坐标轴占满整个画布
      self.fig.subplots_adjust(left=0.05, right=0.95, top=0.95, bottom=0.05)
      
      # 如果是双Y轴情况,需要重新调整子图位置
      if ax in :
            # 移除原来的坐标轴并重新创建以重新布局
            self.ax3.remove()
            self.ax3r.remove()
            
            # 创建占满整个画布的坐标轴
            self.ax3 = self.fig.add_subplot(111)
            self.ax3r = self.ax3.twinx()
            
            # 这里需要重新绘制原始数据(为了示例,我们只创建空坐标轴)
            # 实际应用中,需要保存原始数据并重新绘制
      
      self.is_zoomed = True
      self.current_zoomed_axes = ax
      self.fig.canvas.draw()
   
    def restore_layout(self):
      """恢复原始布局"""
      # 恢复所有坐标轴的可见性
      for ax in self.original_layout['axes']:
            ax.set_visible(True)
      
      # 恢复原始布局设置
      self.fig.subplots_adjust(**self.original_layout['fig'])
      
      # 如果之前放大的是双Y轴,需要恢复原始布局
      if self.current_zoomed_axes in :
            # 清除当前坐标轴
            plt.clf()
            
            # 按照原始布局重新创建所有子图
            self.gs = gridspec.GridSpec(nrows=2, ncols=3)
            self.ax1 = self.fig.add_subplot(self.gs)
            self.ax2 = self.fig.add_subplot(self.gs)
            self.ax3 = self.fig.add_subplot(self.gs)
            self.ax3r = self.ax3.twinx()
            self.ax4 = self.fig.add_subplot(self.gs)
            self.ax5_6 = self.fig.add_subplot(self.gs)
            
            # 这里需要重新绘制原始数据
      
      self.is_zoomed = False
      self.current_zoomed_axes = None
      self.bind_click_events()# 重新绑定事件
      self.fig.canvas.draw()

# 使用示例
if __name__ == "__main__":
    interactive_fig = InteractiveFigure()
   
    # 为每个子图添加一些示例数据
    interactive_fig.ax1.plot(, )
    interactive_fig.ax1.set_title("子图1")
   
    interactive_fig.ax2.plot(, )
    interactive_fig.ax2.set_title("子图2")
   
    interactive_fig.ax3.plot(, , 'r-')
    interactive_fig.ax3.set_title("子图3(双Y轴)")
    interactive_fig.ax3.set_ylabel("左Y轴", color='r')
   
    interactive_fig.ax3r.plot(, , 'b-')
    interactive_fig.ax3r.set_ylabel("右Y轴", color='b')
   
    interactive_fig.ax4.plot(, )
    interactive_fig.ax4.set_title("子图4")
   
    interactive_fig.ax5_6.plot(, )
    interactive_fig.ax5_6.set_title("子图5-6")
   
    plt.show()


关键实现要点:

1. zoom_axes()方法:隐藏其他子图,将被点击的子图放大到全屏
   - 对于普通子图:直接设置该子图为可见,其他为不可见
   - 对于双Y轴子图:需要同时显示主坐标轴和双生坐标轴

2. restore_layout()方法:恢复原始布局
   - 重新设置所有子图为可见
   - 恢复原始的布局参数
   - 对于双Y轴子图,需要重新创建坐标轴以确保布局正确

3. 事件绑定:
   - 为每个子图绑定点击事件(跳过双生坐标轴避免重复)
   - 点击时判断当前状态,执行放大或恢复操作

4. 状态管理:
   - is_zoomed:标记是否处于放大状态
   - current_zoomed_axes:记录当前被放大的坐标轴
   - original_layout:保存原始布局信息用于恢复

注意事项:
- 在实际应用中,需要保存每个子图的绘图数据,在恢复布局时重新绘制
- 双Y轴子图需要特殊处理,确保两个坐标轴都能正确显示和隐藏
- 可以通过调整subplots_adjust参数来优化放大时的边距

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

kerln888 发表于 2026-2-20 01:10:57

@FishC matplotlib如何创建一个仪表盘

FishC 发表于 2026-2-20 01:11:14

kerln888 发表于 2026-02-20 01:10
@FishC matplotlib如何创建一个仪表盘

FishC解答:使用 matplotlib 创建仪表盘,可以结合极坐标和图形元素绘制。以下是一个简单示例:
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111, projection='polar')

# 设置角度范围(0到180度,转换为弧度)
theta = np.linspace(0, np.pi, 100)
# 绘制半圆背景
ax.plot(theta, *100, color='gray', linewidth=20, alpha=0.3)

# 设置刻度范围和标签
ax.set_ylim(0, 1)
ax.set_xticks(np.linspace(0, np.pi, 5))
ax.set_xticklabels(['0', '45', '90', '135', '180'])

# 绘制指针(例如指向90度位置)
pointer_angle = np.pi / 2# 90度
ax.plot(, , color='red', linewidth=4)

# 隐藏径向标签和网格
ax.set_yticklabels([])
ax.grid(True)

plt.show()


[*]使用 projection='polar' 创建极坐标轴。
[*]通过 np.linspace 生成角度数据,绘制半圆弧作为仪表盘背景。
[*]用 ax.plot 绘制指针,通过调整角度和半径控制指向。
[*]隐藏径向标签并使用网格线增强可读性。


如需更复杂效果(如渐变颜色、多指针),可叠加多个绘图元素或使用 patches 模块绘制扇形。

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

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

@FishC matplotlib中,使用axis.bar_label(bar)来显示柱状图数值,如何实现值为0的数值不显示?

FishC 发表于 2026-2-22 17:24:19

kerln888 发表于 2026-02-22 17:23
@FishC matplotlib中,使用axis.bar_label(bar)来显示 ...

在 matplotlib 中,可以通过自定义标签列表来控制柱状图数值的显示,将值为 0 的标签设置为空字符串即可隐藏。

示例代码如下:


import matplotlib.pyplot as plt

# 示例数据
categories = ['A', 'B', 'C', 'D']
values =

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

# 生成自定义标签:0值对应空字符串
labels = ['' if v == 0 else str(v) for v in values]

# 添加自定义标签到柱状图
ax.bar_label(bars, labels=labels)

plt.show()


这样,值为 0 的柱子上就不会显示数值标签了。

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

kerln888 发表于 2026-2-22 18:00:09

@FishC matplotlib中,barh柱状图,legend的顺序和柱子的顺序是相反的,怎么解决

FishC 发表于 2026-2-22 18:00:38

kerln888 发表于 2026-02-22 18:00
@FishC matplotlib中,barh柱状图,legend的顺序和柱 ...

matplotlib中,barh柱状图,legend的顺序和柱子的顺序是相反的,怎么解决

这是因为 plt.legend() 默认按照 Artist 对象的添加顺序生成图例。在绘制水平柱状图时,数据通常从下往上绘制,导致图例顺序与视觉顺序相反。

解决方法:手动指定 handles 和 labels 的顺序,使其与柱子的显示顺序一致。

具体步骤:
1. 在绘图时收集返回的柱状图对象(BarContainer)
2. 将 handles(图形对象)和 labels(标签)按需要的顺序排序
3. 将排序后的 handles 和 labels 传递给 plt.legend()

示例代码:

import matplotlib.pyplot as plt

# 示例数据
categories = ['A', 'B', 'C', 'D']
values =
colors = ['red', 'green', 'blue', 'orange']

# 绘制柱状图,并收集返回的图形对象
bars = []
for i, (cat, val, color) in enumerate(zip(categories, values, colors)):
    bar = plt.barh(cat, val, color=color, label=cat)
    bars.append(bar)

# 获取当前坐标轴
ax = plt.gca()

# 获取当前的handles和labels
handles, labels = ax.get_legend_handles_labels()

# 反转顺序(使图例顺序与柱子从上到下的顺序一致)
# 如果希望图例顺序与柱子从下到上的顺序一致,则不需要反转
handles = handles[::-1]
labels = labels[::-1]

# 使用调整后的顺序创建图例
plt.legend(handles, labels)

plt.show()


如果使用单个 barh 调用绘制多个系列:

import numpy as np

# 示例数据(多个系列)
data = {
    'Series1': ,
    'Series2': ,
    'Series3':
}
categories = ['A', 'B', 'C', 'D']

# 绘制分组柱状图
fig, ax = plt.subplots()
bar_containers = []
colors = ['red', 'green', 'blue']

for (label, values), color in zip(data.items(), colors):
    container = ax.barh(categories, values, label=label, color=color)
    bar_containers.append(container)

# 获取handles和labels并反转顺序
handles, labels = ax.get_legend_handles_labels()
handles = handles[::-1]
labels = labels[::-1]

# 应用调整后的图例
ax.legend(handles, labels)

plt.show()


关键点:
1. 使用 ax.get_legend_handles_labels() 获取当前的对象和标签
2. 根据需要调整顺序(通常使用 [::-1] 进行反转)
3. 通过 ax.legend(handles, labels) 应用调整后的图例

这样就能让图例顺序与柱子的显示顺序保持一致了。

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

kerln888 发表于 2026-2-22 18:38:42

@FishC matplotlib可以给子图添加悬停功能吗??
页: 16 17 18 19 20 21 22 23 24 25 [26] 27 28 29 30 31 32 33 34
查看完整版本: html5 左边菜单栏保持展开或者关闭的状态