Skip to content

Commit fa10e29

Browse files
committed
ENH: read_clipboard function using code from IPython, GH #300
1 parent 90de456 commit fa10e29

File tree

5 files changed

+99
-1
lines changed

5 files changed

+99
-1
lines changed

RELEASE.rst

+2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ pandas 0.5.1
6161
- Add bar plot option to `DataFrame.plot` (PR #348)
6262
- Add `idxmin` and `idxmax` functions to Series and DataFrame for computing
6363
index labels achieving maximum and minimum values (PR #286)
64+
- Add `read_clipboard` function for parsing DataFrame from OS clipboard,
65+
should work across platforms (GH #300)
6466
6567
**Improvements to existing features**
6668

pandas/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from pandas.core.api import *
2323
from pandas.core.common import set_printoptions
2424
from pandas.core.common import set_eng_float_format
25-
from pandas.io.parsers import read_csv, read_table, ExcelFile
25+
from pandas.io.parsers import read_csv, read_table, read_clipboard, ExcelFile
2626
from pandas.io.pytables import HDFStore
2727
from pandas.stats.api import *
2828
from pandas.util.testing import debug

pandas/io/parsers.py

+13
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,19 @@ def read_table(filepath_or_buffer, sep='\t', header=0, index_col=None,
7575
nrows=nrows, iterator=iterator, chunksize=chunksize,
7676
skip_footer=skip_footer, converters=converters)
7777

78+
def read_clipboard(**kwargs): # pragma: no cover
79+
"""
80+
Read text from clipboard and pass to read_table. See read_table for the full
81+
argument list
82+
83+
Returns
84+
-------
85+
parsed : DataFrame
86+
"""
87+
from pandas.util.clipboard import clipboard_get
88+
text = clipboard_get()
89+
return read_table(StringIO(text), **kwargs)
90+
7891
_parser_params = """Also supports optionally iterating or breaking of the file
7992
into chunks.
8093

pandas/util/clipboard.py

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
"""
2+
Taken from the IPython project http://ipython.org
3+
4+
Used under the terms of the BSD license
5+
"""
6+
7+
import subprocess
8+
import sys
9+
10+
def clipboard_get():
11+
""" Get text from the clipboard.
12+
"""
13+
if sys.platform == 'win32':
14+
try:
15+
return win32_clipboard_get()
16+
except Exception:
17+
pass
18+
elif sys.platform == 'darwin':
19+
try:
20+
return osx_clipboard_get()
21+
except Exception:
22+
pass
23+
return tkinter_clipboard_get()
24+
25+
def win32_clipboard_get():
26+
""" Get the current clipboard's text on Windows.
27+
28+
Requires Mark Hammond's pywin32 extensions.
29+
"""
30+
try:
31+
import win32clipboard
32+
except ImportError:
33+
message = ("Getting text from the clipboard requires the pywin32 "
34+
"extensions: http://sourceforge.net/projects/pywin32/")
35+
raise Exception(message)
36+
win32clipboard.OpenClipboard()
37+
text = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT)
38+
# FIXME: convert \r\n to \n?
39+
win32clipboard.CloseClipboard()
40+
return text
41+
42+
def osx_clipboard_get():
43+
""" Get the clipboard's text on OS X.
44+
"""
45+
p = subprocess.Popen(['pbpaste', '-Prefer', 'ascii'],
46+
stdout=subprocess.PIPE)
47+
text, stderr = p.communicate()
48+
# Text comes in with old Mac \r line endings. Change them to \n.
49+
text = text.replace('\r', '\n')
50+
return text
51+
52+
def tkinter_clipboard_get():
53+
""" Get the clipboard's text using Tkinter.
54+
55+
This is the default on systems that are not Windows or OS X. It may
56+
interfere with other UI toolkits and should be replaced with an
57+
implementation that uses that toolkit.
58+
"""
59+
try:
60+
import Tkinter
61+
except ImportError:
62+
message = ("Getting text from the clipboard on this platform "
63+
"requires Tkinter.")
64+
raise Exception(message)
65+
root = Tkinter.Tk()
66+
root.withdraw()
67+
text = root.clipboard_get()
68+
root.destroy()
69+
return text

scripts/boxplot_test.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import matplotlib.pyplot as plt
2+
3+
import random
4+
import pandas.util.testing as tm
5+
tm.N = 1000
6+
df = tm.makeTimeDataFrame()
7+
import string
8+
foo = list(string.letters[:5]) * 200
9+
df['indic'] = list(string.letters[:5]) * 200
10+
random.shuffle(foo)
11+
df['indic2'] = foo
12+
df.boxplot(by=['indic', 'indic2'], fontsize=8, rot=90)
13+
14+
plt.show()

0 commit comments

Comments
 (0)