Separate scrap and production by area I'm looking for feedback on things that can be streamlined in each section. The data it creates is all needed whether it's used in a graph or not so I can't get rid of anything, just combine steps maybe.

import pandas as pd
from matplotlib import pyplot as plt
import seaborn as sns
data = pd.read_csv("C:\\Users\\eb2547\\Desktop\\python code for work\\2017 TB.csv")

# Scrap separation
noNan = data[['Quantity','Scrap Cause']].dropna()
scrap = noNan.groupby('Scrap Cause').sum()


# Hanging production
hangdata = data[(data['Transaction Description'].str.contains('INVM') == True) &amp;
                (data['Location No'] == 'SF HANK STAGING')]
hangprod = hangdata['Quantity'].sum()


# Tapered production


# Wrapper production
wrapdatatobug = data[(data['Transaction Description'] == 'INVM-ISS') &amp;
                (data['Location No'].str.contains('BUG') == True)]
wrapprodtobug = wrapdatatobug['Quantity'].sum()
wrapdatatobox = data[(data['Transaction Description'] == 'OOREC') &amp;
                     (data['Location No'].str.contains('BOX ASSEMBLY-WRAP') == True)]
wrapprodtobox = wrapdatatobox['Quantity'].sum()
wrapscrap = data[(data['Scrap Cause'].str.contains('W') == True)]
wrapscraptotal = wrapscrap['Quantity'].sum()
wrapprodtotal = wrapprodtobug + wrapprodtobox

# Cut Piece production
cpdata = data[(data['Transaction Description'] == 'OOREC') &amp;
               (data['Location No'].str.contains('BOX ASSEMBLY-CP') == True)]
cpprod = cpdata['Quantity'].sum()
cpscrap = data[(data['Scrap Cause'].str.contains('C') == True)]
cpscraptotal = cpscrap['Quantity'].sum()

# Graphs of scrap data
wrapscrap2 = scrap[(scrap.index.str.contains('W') == True)]
cpscrap2 = scrap[(scrap.index.str.contains('C') == True)]
spinscrap = scrap[(scrap.index).str.contains('S') == True]
def Wrap_Scrap():
    fix, ax = plt.subplots(figsize=(10,4))
    sns.barplot(data=wrapscrap2,x=wrapscrap2.index,y='Quantity')
def CP_Scrap():
    fix, ax = plt.subplots(figsize=(10,4))
    sns.barplot(data=cpscrap2,x=cpscrap2.index,y='Quantity')

# Graph of production
prodoverview = pd.DataFrame([hangprod,wrapprodtotal,cpprod],
                            index=['Hanging','Wrapping','CP'],
                            columns=['Quantity'])
def Prod_Graph():
    fix, ax = plt.subplots(figsize=(10,4))
    sns.barplot(data=prodoverview,x=prodoverview.index,y='Quantity')
efficiency

Overall, the code looks idiomatic and sensible, no major issues. But you want to tweak it for efficiency. Here are some things you might try.

Most importantly, instrument elapsed time, so you can tell if a tweak is useful:

    t0 = time.time()
    ...
    elapsed = time.time() - t0


And definitely use the profiler, so you know where to focus your efforts.

Ok, with that in hand, it looks like you need to synthesize some boolean columns. There are several columns that you repeatedly inspect, e.g. Transaction Description. Perhaps you could add them to the spreadsheet, to avoid repeatedly processing unchanging data? Another approach would be to build up a list of rows and then do data = pd.DataFrame(rows). This would let you examine each Transaction Description once and derive a couple of columns. But frankly, I'm skeptical this would improve your timings at all, the code looks fine as is.

style

Do use a pep8 linter: flake8, and follow its advice.

In hard-to-read identifiers like spinscrap, introduce an underscore so it is clear to the Gentle Reader where word breaks are.