python 棒棒糖图

结果:

复制代码
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np


def lolly_plot(x, y, color_lis, breaks, back_color,
               title, sub_title):
    # 获取每个点的颜色
    colors = [assign_color(temperature, breaks, color_lis) for temperature in temperature_changes]

    # 创建图形
    fig, ax = plt.subplots(figsize=(10, 12))

    # 绘制棒棒糖
    ax.vlines(x=x, ymin=0, ymax=y, color=colors, alpha=0.8, linewidth=2)  # 竖线
    ax.scatter(x, y, color=colors, s=50, zorder=3)  # 点

    # 添加水平线(0℃、-0.4℃、0.8℃)
    ax.axhline(0.8, color=color_lis[-1], linewidth=1, alpha=0.5)
    ax.axhline(0.4, color=color_lis[4], linewidth=1, alpha=0.5)
    ax.axhline(0, color='black', linewidth=1)
    ax.axhline(-0.4, color=color_lis[0], linewidth=1, alpha=0.5)

    # 设置坐标轴
    ax.set_xlim(1880, 2020)
    ax.set_ylim(-0.5, 1.0)
    ax.set_xticks(np.arange(1880, 2021, 20))
    ax.set_yticks([-0.4, 0, 0.4, 0.8])
    # 去掉顶部和右侧的边框线
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)

    # 设置标签
    ax.set_title(title, fontsize=20, weight='bold', ha='left', x=0.02)
    ax.text(0.02, 0.99, sub_title, transform=ax.transAxes, fontsize=12, va='top', color='gray')

    # 设置背景颜色
    fig.patch.set_color(back_color)
    ax.patch.set_color(back_color)

    # 显示图像
    plt.tight_layout()  # 让图表更贴近边框
    plt.show()


# 分段赋色规则(对应原图的分块颜色)
def assign_color(value, breaks, colors):
    """
    分段赋色。小于等于第一个断点为第一个区间,大于第一个断点、小于等于第二个断点为第二个区间...,大于最后一个断点为最后一个区间。
    breaks:断点。 breaks至少比colors少一个。
    colors:颜色。从数值最低的颜色到数值最高的颜色,依次排列。
    """
    # 从小到大,依次排列断点。
    breaks = list(breaks)
    breaks.sort(reverse=False)  # 升序排列
    # bisect_left: 二分法查找某个值所在的区间。(若为边界值,则落入左侧区间。)
    index = bisect_left(breaks, value)
    return colors[index]


if __name__ == '__main__':
    # 年份数据
    years = np.arange(1880, 2021)

    # 模拟温度变化数据,接近实际趋势
    temperature_changes = np.zeros(len(years))
    # 分段设定温度变化趋势,并加入波动
    np.random.seed(0)
    temperature_changes[0:60] = np.linspace(-.5, -.2, 60) + np.random.normal(0, .05, 60)  # 1880-1940 年
    temperature_changes[60:100] = np.linspace(-.2, .1, 40) + np.random.normal(0, .03, 40)  # 1940-1980 年
    temperature_changes[100:] = np.linspace(.1, .9, len(years) - 100) + np.random.normal(0, .02, len(years) - 100)

    # 为每个温度区间分配颜色
    color_lis = ['#212B4E', '#0571B6', '#17B3BA', '#FDBE85', '#D94701', '#871A03']
    breaks = [-0.25, -0.1, 0, 0.3, 0.52]
    back_color = '#FEFAEF'

    # 设置标题
    title = "Global Land-Ocean Temperature Index"
    text = "Change in global surface temperature compared to the long-term average\nfrom 1951 to 1980"

    lolly_plot(years, temperature_changes, color_lis, breaks, back_color, title, text)
相关推荐
Python图像识别1 天前
71_基于深度学习的布料瑕疵检测识别系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)
python·深度学习·yolo
千码君20161 天前
React Native:从react的解构看编程众多语言中的解构
java·javascript·python·react native·react.js·解包·解构
淮北4941 天前
windows安装minicoda
windows·python·conda
爱喝白开水a1 天前
LangChain 基础系列之 Prompt 工程详解:从设计原理到实战模板_langchain prompt
开发语言·数据库·人工智能·python·langchain·prompt·知识图谱
默默coding的程序猿1 天前
3.git的分支携带问题是什么?怎么解决?
java·git·python·svn·gitee·github·intellij-idea
新子y1 天前
【小白笔记】PyTorch 和 Python 基础的这些问题
pytorch·笔记·python
我是李武涯1 天前
PyTorch DataLoader 高级用法
人工智能·pytorch·python
Lynnxiaowen1 天前
今天我们开始学习python语句和模块
linux·运维·开发语言·python·学习
ThreeAu.1 天前
pytest 实战:用例管理、插件技巧、断言详解
python·单元测试·pytest·测试开发工程师
资源补给站1 天前
服务器高效操作指南:Python 环境退出与 Linux 终端快捷键全解析
linux·服务器·python