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)
相关推荐
luckys.one3 小时前
第9篇:Freqtrade量化交易之config.json 基础入门与初始化
javascript·数据库·python·mysql·算法·json·区块链
大翻哥哥4 小时前
Python 2025:量化金融与智能交易的新纪元
开发语言·python·金融
zhousenshan6 小时前
Python爬虫常用框架
开发语言·爬虫·python
IMER SIMPLE6 小时前
人工智能-python-深度学习-经典神经网络AlexNet
人工智能·python·深度学习
CodeCraft Studio6 小时前
国产化Word处理组件Spire.DOC教程:使用 Python 将 Markdown 转换为 HTML 的详细教程
python·html·word·markdown·国产化·spire.doc·文档格式转换
专注API从业者7 小时前
Python/Java 代码示例:手把手教程调用 1688 API 获取商品详情实时数据
java·linux·数据库·python
java1234_小锋7 小时前
[免费]基于Python的协同过滤电影推荐系统(Django+Vue+sqlite+爬虫)【论文+源码+SQL脚本】
python·django·电影推荐系统·协同过滤
看海天一色听风起雨落8 小时前
Python学习之装饰器
开发语言·python·学习
XiaoMu_0018 小时前
基于Python+Streamlit的旅游数据分析与预测系统:从数据可视化到机器学习预测的完整实现
python·信息可视化·旅游
THMAIL8 小时前
深度学习从入门到精通 - 生成对抗网络(GAN)实战:创造逼真图像的魔法艺术
人工智能·python·深度学习·神经网络·机器学习·生成对抗网络·cnn