从 python 创建“经济学人”风格的图表

2023-11-23

使用 python 和 marplotlib 以及像seaborn这样的工具,我想创建一个像《经济学人》中的这样的图表(因为我认为这种风格很棒。)

Greece Debt

这是一个时间序列图,我想要重现的关键是水平网格线,其标签与带有刻度线的较低水平轴相匹配。网格线两端的不同颜色标签将是一个额外的好处,并带有相应的标题(左右对齐)。注释将是双重好处。

我尝试使用seaborn制作类似的东西,但无法迈出第一步。


并不完美(我使用它的时间不长),但为了让您了解需要使用哪种 Matplotlib 方法来按照您想要的方式自定义绘图,下面有一些代码。

请注意,要微调这样的绘图,很难将内容和演示分开(您可能必须手动设置刻度标签等,因此如果您更改数据,它不会自动工作)。经济学家图形人员显然这样做是因为他们似乎把左上角的刻度标签搞错了(280 应该是 260)。

# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as ticker
from datetime import datetime

# Load in some sample data
bond_yields = np.loadtxt('bond_yields.txt',
                         converters={0: mdates.strpdate2num('%Y-%m-%d')},
                         dtype = {'names': ('date', 'bond_yield'),
                                  'formats': (datetime, float)})
bank_deposits = np.loadtxt('bank_deposits.txt',
                         converters={0: mdates.strpdate2num('%Y-%m-%d')},
                         dtype = {'names': ('date', 'bank_deposits'),
                                  'formats': (datetime, float)})

# Bond yields line is in light blue, bank deposits line in dark red:
bond_yield_color = (0.424, 0.153, 0.090)
bank_deposits_color = (0.255, 0.627, 0.843)

# Set up a figure, and twin the x-axis so we can have two different y-axes
fig = plt.figure(figsize=(8, 4), frameon=False, facecolor='white')
ax1 = fig.add_subplot(111)
ax2 = ax1.twinx()
# Make sure the gridlines don't end up on top of the plotted data
ax1.set_axisbelow(True)
ax2.set_axisbelow(True)

# The light gray, horizontal gridlines
ax1.yaxis.grid(True, color='0.65', ls='-', lw=1.5, zorder=0)

# Plot the data
l1, = ax1.plot(bank_deposits['date'], bank_deposits['bank_deposits'],
         c=bank_deposits_color, lw=3.5)
l2, = ax2.plot(bond_yields['date'], bond_yields['bond_yield'],
         c=bond_yield_color, lw=3.5)

# Set the y-tick ranges: chosen so that ax2 labels will match the ax1 gridlines
ax1.set_yticks(range(120,280,20))
ax2.set_yticks(range(0, 40, 5))

# Turn off spines left, top, bottom and right (do it twice because of the twinning)
ax1.spines['left'].set_visible(False)
ax1.spines['right'].set_visible(False)
ax1.spines['top'].set_visible(False)
ax2.spines['left'].set_visible(False)
ax2.spines['right'].set_visible(False)
ax2.spines['top'].set_visible(False)
ax1.spines['bottom'].set_visible(False)
ax2.spines['bottom'].set_visible(False)
# We do want ticks on the bottom x-axis only
ax1.xaxis.set_ticks_position('bottom')
ax2.xaxis.set_ticks_position('bottom')

# Remove ticks from the y-axes
ax1.tick_params(axis='y', length=0)
ax2.tick_params(axis='y', length=0)

# Set tick-labels for the two y-axes in the appropriate colors
for tick_label in ax1.yaxis.get_ticklabels():
    tick_label.set_fontsize(12)
    tick_label.set_color(bank_deposits_color)
for tick_label in ax2.yaxis.get_ticklabels():
    tick_label.set_fontsize(12)
    tick_label.set_color(bond_yield_color)

# Set the x-axis tick marks to two-digit years
ax1.xaxis.set_major_locator(mdates.YearLocator())
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%y'))

# Tweak the x-axis tick label sizes
for tick in ax1.xaxis.get_major_ticks():
    tick.label.set_fontsize(12)
    tick.label.set_horizontalalignment('center')

# Lengthen the bottom x-ticks and set them to dark gray
ax1.tick_params(direction='in', axis='x', length=7, color='0.1')

# Add the line legends as annotations
ax1.annotate(u'private-sector bank deposits, €bn', xy=(0.09, 0.95),
             xycoords='figure fraction', size=12, color=bank_deposits_color,
             fontstyle='italic')
ax2.annotate(u'ten-year government bond yield, %', xy=(0.6, 0.95),
             xycoords='figure fraction', size=12, color=bond_yield_color,
             fontstyle='italic')

# Add an annotation at the date of the first bail-out. relpos=(0,0) ensures
# that the label lines up on the right of a vertical line
first_bailout_date = datetime.strptime('2010-05-02', '%Y-%m-%d')
xpos = mdates.date2num(first_bailout_date)
ax1.annotate(u'FIRST BAIL-OUT', xy=(xpos, 120), xytext=(xpos, 250), color='r',
             arrowprops=dict(arrowstyle='-', edgecolor='r', ls='dashed',
             relpos=(0,0)), fontsize=9, fontstyle='italic')

fig.savefig('fig.png', facecolor=fig.get_facecolor(), edgecolor='none')

enter image description here

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 python 创建“经济学人”风格的图表 的相关文章

随机推荐

  • android tv - 重新加载适配器数据

    我想重新加载浏览片段中的一些行数据 基本上我想重置适配器数据而不在浏览片段中造成类似闪存的效果 知道如何做到吗 就像是notifyDataSetChanged 在列表视图中 Thanx 这将刷新数据而不丢失当前位置 for int i 0
  • 监视 Windows 中进程执行的某些系统调用

    我希望能够监视进程进行的某些系统调用 主要是文件 I O 调用 在Linux上我可能可以使用strace具有合适的参数 但如何在 Windows 上执行此操作 我主要感兴趣的是运行一个进程并找出它已读取和写入的文件 我想从另一个进程以编程方
  • 继承自Set.prototype

    这真的很困扰我 我可以轻松创建一个继承方法的新类Array prototype var MyArray function MyArray prototype Array prototype var myArray new MyArray m
  • 如何在 DDEV Web 容器中添加和使用 nvm?

    目前 DDEV Web 容器不附带 nvm 节点版本管理器 如何通过 DDEV config yaml 文件添加和使用它 在当前的 ddev v1 19 中 默认安装了 nvm 并且可以与ddev nvm 所以您不必执行任何操作 看docs
  • Python:导入模块导入模块

    所以在文件 foo 中我导入模块 import lib helper functions import lib config 在 helper functions py 中 我有 import config 当我运行 foo 的 main
  • Jmeter中的吞吐量计算

    Attached is the Summary Report for my tests 请帮我理解JMeter的吞吐量值是如何计算的 例如第一条线路的吞吐量53 1 min 这个数字是JMeter用什么公式计算出来的 另外 想知道后续测试中
  • 我如何通过 Objective-c 访问 iPhone 文件?

    我注意到有一些软件 例如 iExplorer 可以让您从 Mac 访问 iPhone 设备上的文件 现在我的问题是 如何通过 Objective c 访问 iPhone 文件 这仅用于教育目的 我找到了这个 https github com
  • 如何知道应用程序运行在什么 Mac 操作系统上?

    我在一些项目中看到过类似的东西 if code endif 但我现在找不到了 例如 如果应用程序在 10 8 上运行 则该应用程序会执行 1 件事 否则该应用程序会执行其他操作 编写什么代码来检查它是否在 10 8 上运行 Thanks 你
  • Mod重写问题

    和其他许多人一样 我在 apache 中进行一些非常简单的 mod rewriting 时遇到了问题 我的 htaccess 中有以下内容 Options FollowSymLinks RewriteEngine on RewriteBas
  • 如何将 Rust 内存分配器用于可提供分配器的 C 库?

    我正在编写与 C 库的 Rust 绑定 该库可以选择使用第三方内存分配器 它的界面如下所示 struct allocator void alloc void old uint void free void 我猜 相应的 Rust 结构如下
  • 当 MKMapView 显示UserLocation == YES 时隐藏 MKUserLocation

    设置后mapView showsUserLocation为 true 是否可以在不显示 MKUserLocation 气泡的情况下接收位置更新 返回零mapView viewForAnnotation 只是显示气泡 返回任何其他类型的注释会
  • 选择的图库默认项目位于中心[重复]

    这个问题在这里已经有答案了 可能的重复 android图库图像位置问题 我在我的应用程序中使用图库视图 现在当我运行代码时 图库默认选择的项目为 1 位于中心 左侧为空白 相反 我不希望左侧有 1 项被选中 此外 单击任何图库项目不应将该项
  • std::unique_ptr 的“无抛出取消引用”

    我用 C 编写代码 使用std unique ptr u处理一个std string资源 我想取消引用u这样我就可以通过std string的电话std string复制构造函数 std string copy new std string
  • Android:列表视图中的指南针+距离

    我想你们都尝试过地图中的 Google Places 这是您附近的 POI 列表 我真的很想在我的应用程序中使用 GPS 坐标列表来实现相同的功能 但这看起来非常复杂 制作带有距离和小箭头的列表视图非常容易 但我不明白如何在用户每次移动手机
  • 我的内部 API 类应该全部放在一个包中吗?

    我正在努力打包供公众使用的 API 因此 我试图限制仅向那些我希望公开且可支持的方法公开的方法 当然 在此之下还有许多受限的访问方法 问题是我有很多内部代码需要访问这些受限制的方法而不将这些方法公开 这会产生两个问题 我无法创建接口 类之间
  • 将声音帧从 8Khz 重新采样/上采样到 48Khz (Java/Android)

    我正在尝试为andriod开发的应用程序 以48Khz PCM 16位和单声道 记录帧并将它们发送到网络 此外 还有 8Khz 的传入音频流 因此 我接收 8Khz 采样帧并播放它们 我的 AudioTrack 对象设置为 8Khz 但是在
  • 在 C++ 中重写成员变量

    我在一些 C 代码中遇到了一些棘手的问题 这最容易使用代码来描述 我有类似的课程 class MyVarBase class MyVar public MyVarBase int Foo class MyBase public MyBase
  • 如何允许 std:string 参数为 NULL?

    我有一个函数foo const std string str 如果你使用它调用它它会崩溃foo NULL 我该怎么做才能防止它崩溃 std string 有一个采用 const char 参数的构造函数 当您将 NULL 传递给它时 该构造
  • C++ 使变量类型取决于用户输入

    我想要一个创建数组用于测试目的的函数 这个想法是让用户选择数组将包含的元素类型 int float double 然后它必须返回所选类型的数组并且main必须将其用作参数 我知道这是使用空指针 但如果有人能为我提供一个例子 我会很高兴 这就
  • 从 python 创建“经济学人”风格的图表

    使用 python 和 marplotlib 以及像seaborn这样的工具 我想创建一个像 经济学人 中的这样的图表 因为我认为这种风格很棒 这是一个时间序列图 我想要重现的关键是水平网格线 其标签与带有刻度线的较低水平轴相匹配 网格线两