简体   繁体   中英

How to plot a Arrow and Range plot in Python?

Arrow plots are a relatively new chart type. They show how data points (eg life expectancy, election results) of different categories (eg countries, parties) have changed between two dates (eg decades, years, days). Arrow plots show exactly two dates. If you want to show multiple time points for your data points, consider a line chart. If your emphasis is on the gap between the dots rather than the time that has passed between them, then a range plot is the better choice. If you don't have time points and just want to show one or multiple dots on a line, consider a dot plot.

在此处输入图像描述

Source: economist- Americans are getting more nervous about what they say in public

在此处输入图像描述

Source : bundestag.de Get the data

I'm just curious to know if there is any python package that can be used to plot a similar kind of Arrow plots. My knowledge of visualization was minimum. I'm not asking for the exact replicate of the above Plot, a similar plot would be highly appreciated.

I'm open to new ideas and approaches and wanted to put some feelers out before diving into getting started

Can it be possible to plot the above plot with Python if YES, Which package would be used to plot the above plot? Can anybody shed some light on plotting the above plot with Python? I would be happy to receive any leads on it from you.

For this type of graph, I think the most time-consuming type is MPL, but I wrote the code in a way to mimic the second example of the expected output. Basically, it is created with arrows and annotations.

import pandas as pd
import numpy as np
import io

data = '''
Party 2009 2013
CDU/CSU 33.8 41.5
SPD 23.0 25.7
LINKE 11.9 8.6
GRÜNE 10.7 8.4
FDP 14.6 4.8
'''

df = pd.read_csv(io.StringIO(data), delim_whitespace=True)

import matplotlib.pyplot as plt
from matplotlib import colors as mcolors
colors = mcolors.TABLEAU_COLORS

fig, ax = plt.subplots(figsize=(10,4))
plt.rcParams.update({'axes.spines.top': False, 'axes.spines.right': False})

for (idx,row), c in zip(df.iterrows(),colors):
    cols = colors.keys()
    ax.arrow(row['2009'], idx, row['2013']-row['2009'], 0, head_width=0.2, head_length=0.7, width=0.03, fc=c, ec=c)
    if row['2009'] < row['2013']:
        ax.annotate('{}'.format(row['2009']), xy=(row['2009'], idx), xytext=(row['2009']-2.5,idx-0.05), xycoords='data', color=c)
        ax.annotate('{}'.format(row['2013']), xy=(row['2013'], idx), xytext=(row['2013']+0.9,idx-0.05), xycoords='data', color=c)
    else:
        ax.annotate('{}'.format(row['2009']), xy=(row['2009'], idx), xytext=(row['2009']+0.5,idx-0.05), xycoords='data', color=c)
        ax.annotate('{}'.format(row['2013']), xy=(row['2013'], idx), xytext=(row['2013']-2.5,idx-0.05), xycoords='data', color=c)

    ax.set_yticks(np.arange(len(df)))        
    ax.set_yticklabels(df['Party'])
    ax.grid()
    ax.set_xlim(-5,45)
    ax.tick_params('x', length=0, which='major')
    ax.tick_params('y', length=0, which='major')

ax.annotate('2009', xy=(0.25,0.85), xytext=(0.25,0.93), xycoords='figure fraction', arrowprops=dict(arrowstyle='-'))
ax.annotate('2013', xy=(0.45,0.85), xytext=(0.45,0.93), xycoords='figure fraction', arrowprops=dict(arrowstyle='-'))
plt.show()

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM