<jupyter_start><jupyter_text>Why Carpet Plots?A typical scatter plot allows you to compare the impact of one independent variable (*x-axis*) on one dependent variable (*y-axis*). Carpet plots facilitate trade studies between more than one independent variable.  Example DataImagine you need to deliver a number of items and want to know how much gas for the trip will cost. Total fuel cost is a function of the number of stops on the route. Let's import the required libraries and generate an example dataset.<jupyter_code>%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import plotly
# Generate data with one independent variable (stops)
stops = np.arange(1, 11, 1)
dist = 5
cost = stops * dist * 3 / 30 # $3.00/gal and 30 mpg
cost
plt.plot(stops,cost)
plt.xlabel('Stops')
plt.ylabel('Fuel Cost ($)')
plt.style.use('seaborn-ticks')<jupyter_output><empty_output><jupyter_text>Now let's say we want to determine the total fuel cost as a function of two independent variables: (1) the number of stops on the route, and (2) the average distance between stops. For a range of numbers of stops and distances between stops, we can calculate each respective total fuel cost.<jupyter_code># Generate data with two independent variables (stops, distance)
stops = np.arange(1, 11, 1)
dist = np.arange(10, 41, 5)
stops, dist = np.meshgrid(stops, dist)
cost = (stops * dist * 3 / 30)
cost.shape<jupyter_output><empty_output><jupyter_text>We have a few options to illustrate the relationship of these two independent variables:  Multiple Line PlotsFirst we can plot multiple lines, each representing one value of the second independent variable. For a simple dataset this might work, but it is difficult to visualize the trade-space in this manner especially with more complex datasets.<jupyter_code>for i in [0,1,2,3,4]:
    plt.plot(stops[i:][1],cost[i:][1], label='Dist = {} mi'.format(dist[:,0][i]))
plt.xlabel('Stops')
plt.ylabel('Fuel Cost ($)')
handles, labels = plt.gca().get_legend_handles_labels()
plt.gca().legend(handles, labels)
plt.style.use('seaborn-ticks')<jupyter_output><empty_output><jupyter_text>We could also separate each of these lines into separate [subplots](https://matplotlib.org/examples/pylab_examples/subplots_demo.html), but there again we find difficulty making quick comparisons between each independent variable.   3D Surface PlotWe can get fancy and generate a 3D surface plot of our data. While pretty, this is even more difficult to read in a useful way if we are trading the two independent variables in an effort to converge on the dependent variable. At 17 stops and 24 miles between stops, how much will fuel cost? It's not easy to determine from this plot.<jupyter_code>from mpl_toolkits.mplot3d import axes3d

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

plt.xlabel('Stops')
plt.ylabel('Distance')
ax.plot_wireframe(stops, dist, cost, rstride=1, cstride=1)<jupyter_output><empty_output><jupyter_text>Enter the Carpet PlotThe advantage of carpet plots is the ability to quickly visualize the relative impact of the two independent variables. This can be especially helpful when doing a trade study where multiple variables are in play. Data preparation using `pd.melt()`Pandas has a number of helpful data reshaping methods, and this exercise presents the opportunity to use [`pd.melt()`](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.melt.html). Our starting dataset is an array with the index of one axis representing the first independent variable values (**`stops`**), and the index of the other axis representing the second independent variable values (**`dist`**). The values in the array represent our dependent variable (**`cost`**). You can think of this as the output of an Excel data table, which may at times in fact be the data source. Plotly takes a list of each variable to plot a carpet plot, so we use `pd.melt()` to [tidy](http://www.stat.wvu.edu/~jharner/courses/stat623/docs/tidy-dataJSS.pdf) this data and then convert to lists.<jupyter_code>stops = (pd.DataFrame(stops)
         .melt()
         ['value']
         .tolist())
dist = (pd.DataFrame(dist)
         .melt()
         ['value']
         .tolist())
cost = (pd.DataFrame(cost)
         .melt()
         ['value']
         .tolist())<jupyter_output><empty_output><jupyter_text>Plotting with PlotlyNow that we have a tidy dataset in a list for each variable, we can plot using Plotly. Why Plotly? I have avoided Plotly in the past due to the confusing process of making an account and putting your plots online. But using Plotly's [carpet plot example](https://plot.ly/python/carpet-plot/) and some information from Stackoverflow, I was able to get it to work without the online authentication, which is just fine for a static chart. I would still prefer to use matplotlib, and may tackle that later. For now, here's the code to generate the Plotly carpet plot. Note that when running this, Plotly will generate a HTML file which then presents a prompt to save a .jpeg of your chart.<jupyter_code>import plotly.graph_objs as go
from plotly.graph_objs import Layout,Scatter

trace1 = go.Carpet(
    a = stops,
    b = dist,
    y = cost,
    aaxis = dict(
        tickprefix = '',
        ticksuffix = ' stops',
        smoothing = 1,
        minorgridcount = 9
    ),
    baxis = dict(
        tickprefix = 'Dist = ',
        ticksuffix = ' mi.',
        smoothing = 1,
        minorgridcount = 9
    )
)

plotly.offline.plot({
    "data": [trace1], 
    "layout": Layout(title="Carpet Plot Example",
                     font=dict(family='Arial, sans-serif', 
                               size=18, 
                               color='rgb(0,0,0)'),
                     yaxis=dict(
                         title='Total Fuel Cost ($)',
                         titlefont=dict(
                             family='Arial, sans-serif',
                             size=18
                         ),
                         showticklabels=True
                     ),
                     margin=go.Margin(
                         l=100,
                         r=50)
                    )
},filename='Carpet.html',image='jpeg')<jupyter_output><empty_output><jupyter_text>Great, a carpet plot! Now we can pick any combination of number of stops and distance between stops and easily determine the total fuel cost for the trip.   Future WorkThis has been a brief overview of plotting 3-variable carpet plots in Python with Plotly. In the future, I would also like to:- plot with matplotlib, perhaps starting with [this example](https://github.com/steve855/pyCarpetPlot/blob/master/pyCarpetPlot.py)- demonstrate including more than two independent variables<jupyter_code>%load_ext watermark
%watermark -iv<jupyter_output>matplotlib  2.1.0
pandas      0.21.1
numpy       1.13.3
plotly      2.2.2<jupyter_text>*This post was written entirely in the Jupyter notebook. You can [download](https://github.com/mkudija/blog/blob/master/content/downloads/notebooks/CarpetPlots/CarpetPlots.ipynb) the original notebook.*  Unused Extras<jupyter_code>df = pd.read_excel('CarpetPlotData.xlsx')
df.head()<jupyter_output><empty_output><jupyter_text>Plotting with PlotlyNow that we have a tidy dataset, we can plot using Plotly. Why Plotly? I have avoided Plotly in the past beacuse of the weird partially-open-source-partially-paid model and needing to authenticate online. Using Plotly's [carpet plot example](https://plot.ly/python/carpet-plot/) and some digging on Stackoverflow, I was able to get it to work without the online authentication. I would still prefer to use matplotlib, and may tackle that later. For now, here's the code to generate the Plotly carpet plot:<jupyter_code># # RESOURCES:
# # carpet plots: https://en.wikipedia.org/wiki/Carpet_plot
# # good plotly offline examples: https://github.com/SayaliSonawane/Plotly_Offline_Python/blob/master/Line%20Chart/line_chart.py
# # other python for carpet plots: https://github.com/steve855/pyCarpetPlot/blob/master/pyCarpetPlot.py

# import plotly.graph_objs as go
# from plotly.graph_objs import Layout,Scatter

# trace1 = go.Carpet(
#     a = df.a.tolist(),
#     b = df.b.tolist(),
#     y = df.y.tolist(),
#     aaxis = dict(
#         tickprefix = '',
#         ticksuffix = ' stops',
#         smoothing = 1,
#         minorgridcount = 9
#     ),
#     baxis = dict(
#         tickprefix = 'Dist = ',
#         ticksuffix = ' mi.',
#         smoothing = 1,
#         minorgridcount = 9
#     )
# )

# plotly.offline.plot({
#     "data": [trace1], 
#     "layout": Layout(title="Carpet Plot Example",
#                      font=dict(family='Arial, sans-serif', 
#                                size=18, 
#                                color='rgb(0,0,0)'),
#                      yaxis=dict(
#                          title='Total Trip Cost ($)',
#                          titlefont=dict(
#                              family='Arial, sans-serif',
#                              size=18
#                          ),
#                          showticklabels=True
#                      ),
#                      margin=go.Margin(
#                          l=100,
#                          r=50)
#                     )
# },filename='Carpet.html',image='jpeg')
# subplots
# Four axes, returned as a 2-d array

x = [1, 10]
y1 = [1.0,10.0]
y2 = [2.0, 20.0]
y3 = [3.0, 30.0]
y4 = [4.0, 40.0]
f, axarr = plt.subplots(2, 2)
axarr[0, 0].plot(x, y1)
axarr[0, 0].set_title('d=10')
axarr[0, 1].plot(x, y2)
axarr[0, 1].set_title('d=20')
axarr[1, 0].plot(x, y3)
axarr[1, 0].set_title('d=30')
axarr[1, 1].plot(x, y4)
axarr[1, 1].set_title('d=40')
# Fine-tune figure; hide x ticks for top plots and y ticks for right plots
plt.setp([a.get_xticklabels() for a in axarr[0, :]], visible=False)
plt.setp([a.get_yticklabels() for a in axarr[:, 1]], visible=False)

print(plt.style.available)
data = {'Stops': [1, 5, 10],
      'FuelCost': [2.5, 12.5, 25.0]}
df = pd.DataFrame.from_dict(data)

df.set_index('Stops')['FuelCost'].plot()
plt.ylabel('Fuel Cost ($)')
plt.style.use('seaborn-ticks')
data = {'Stops': [1, 10],
        'd=10': [1.0, 10.0],
        'd=20': [2.0, 20.0],
        'd=30': [3.0, 30.0],
        'd=40': [4.0, 40.0]}
df = pd.DataFrame.from_dict(data)

(df
 .set_index('Stops')[['d=10','d=20','d=30','d=40']]
 .plot()
)
plt.ylabel('Fuel Cost ($)')
plt.show()
from mpl_toolkits.mplot3d import axes3d

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

X = np.arange(1, 10, 1)
Y = np.arange(10, 40, 1)
X, Y = np.meshgrid(X, Y)
Z = np.sqrt(X * Y * 3 / 30)

ax.plot_wireframe(X, Y, Z, rstride=1, cstride=1)
plt.xlabel('Stops')
plt.ylabel('Distance')
from mpl_toolkits.mplot3d import axes3d
from matplotlib import cm

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

X = np.arange(1, 10, 1)
Y = np.arange(10, 40, 1)
X, Y = np.meshgrid(X, Y)
Z = np.sqrt(X * Y * 3 / 30)

surf = ax.plot_surface(X, Y, Z, cmap=cm.Oranges,
                       linewidth=0, antialiased=False)
fig.colorbar(surf, shrink=0.5, aspect=5)

plt.xlabel('Stops')
plt.ylabel('Distance')
%load_ext watermark
%watermark -iv<jupyter_output>The watermark extension is already loaded. To reload it, use:
  %reload_ext watermark
matplotlib  2.1.0
pandas      0.21.1
numpy       1.13.3
plotly      2.2.2
{'fraction_non_alphanumeric': 0.11605177423615391, 'fraction_numerical': 0.02447829532446949, 'mean_word_length': 3.0622317596566524, 'pattern_counts': {'":': 4, '<': 35, '<?xml version=': 0, '>': 35, 'https://': 9, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '457805', 'license': 'MIT', 'n_tokens_mistral': 3846, 'n_tokens_neox': 3596, 'n_words': 1170, 'path': 'docs/downloads/notebooks/CarpetPlots/CarpetPlots.ipynb', 'repo_name': 'Ronak1958/blog', 'size': '11357'}