Matplotlib set year on x axis - python

i would like to have a plot of nasdaq market index that has on x axis the years since 1971 and on y axis the values.
dataframe = pd.read_csv('nasdaq-historical-chart.csv', usecols=[1], engine='python')
dataset = dataframe.values
df = pd.read_csv('nasdaq-historical-chart.csv',parse_dates=True)
df['date'] = pd.to_datetime(df['date'])
df['year'] = df['date'].dt.year
plt.plot(dataset)
plt.figure(figsize=(25,10))
plt.plot(df['year'], dataset)
plt.title('NASDAQ historical chart',fontsize=24)
plt.xlabel('Time',fontsize=14)
plt.ylabel('Value',fontsize=14)
plt.tick_params(axis='both',labelsize=14)
plt.show()
In this way i have the right plot but without years on x axis
If i put:
plt.plot(df['year'], dataset)
i have:
why the plot changed? How can i modify it?

I created some data similar to yours as example, and you can do in a similar way:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({'date':['1971-1-1','1971-1-2','1971-1-3','1971-1-4','1971-1-5','1971-1-6','1971-1-7','1971-1-8','1971-1-9',
'1971-1-10', '1971-1-11', '1971-1-12', '1972-1-1','1972-1-2','1972-1-3','1972-1-4',
'1972-1-5','1972-1-6','1972-1-7','1972-1-8','1972-1-9','1972-1-10', '1972-1-11', '1972-1-12'],
'values':[150, 130, 100, 95, 100, 105, 200, 180, 170, 160, 150, 155, 155, 170, 190, 192, 195, 200, 220,
230, 220, 210, 230, 235]})
print (df)
df['date'] = pd.to_datetime(df['date'], format='%Y-%d-%m')
plt.figure(figsize=(25,10))
plt.plot(df['date'], df['values'])
plt.title('NASDAQ historical chart',fontsize=24)
plt.xlabel('Time',fontsize=14)
plt.ylabel('Value',fontsize=14)
plt.tick_params(axis='both',labelsize=14)
plt.show()

Related

How can I find the Optimal Price Point and Group By ID?

I have a dataframe that looks like this.
import pandas as pd
# intialise data of lists.
data = {'ID':[101762, 101762, 101762, 101762, 102842, 102842, 102842, 102842, 108615, 108615, 108615, 108615, 108615, 108615],
'Year':[2019, 2019, 2019, 2019, 2020, 2020, 2020, 2020, 2021, 2021, 2021, 2021, 2021, 2021],
'Quantity':[60, 80, 88, 75, 50, 55, 62, 58, 100, 105, 112, 110, 98, 95],
'Price':[2000, 3000, 3330, 4000, 850, 900, 915, 980, 1000, 1250, 1400, 1550, 1600, 1850]}
# Create DataFrame
df = pd.DataFrame(data)
# Print the output.
df
Here are some plots of the data.
import matplotlib.pyplot as plt
import seaborn as sns
uniques = df['ID'].unique()
for i in uniques:
fig, ax = plt.subplots()
fig.set_size_inches(4,3)
df_single = df[df['ID']==i]
sns.lineplot(data=df_single, x='Price', y='Quantity')
ax.set(xlabel='Price', ylabel='Quantity')
plt.xticks(rotation=45)
plt.show()
Now, I am trying to find the optimal price to sell something, before quantity sold starts to decline. I think the code below is pretty close, but when I run the code I get '33272.53'. This doesn't make any sense. I am trying to get the optimal price point per ID. How can I do that?
df["% Change in Quantity"] = df["Quantity"].pct_change()
df["% Change in Price"] = df["Price"].pct_change()
df["Price Elasticity"] = df["% Change in Quantity"] / df["% Change in Price"]
df.columns
import pandas as pd
from sklearn.linear_model import LinearRegression
x = df[["Price"]]
y = df["Quantity"]
# Fit a linear regression model to the data
reg = LinearRegression().fit(x, y)
# Find the optimal price that maximizes the quantity sold
optimal_price = reg.intercept_/reg.coef_[0]
optimal_price

X-ticks values consistent with bars [duplicate]

This question already has answers here:
Aligning rotated xticklabels with their respective xticks
(5 answers)
Closed 1 year ago.
Could someone please help me to set my x-ticks with bars. The bars are not consistent with xtick time values as you can see in the image. I have printed my data values of g01, g02 below and code as well. I have tried this solution Python MatplotLib plot x-axis with first x-axis value labeled as 1 (instead of 0), plt.xticks(np.arange(len(g01)), np.arange(1, len(g01)+1)) although then bars are consistent with x-ticks but it changes to numbers 1 to 28. I want time period like in my image.
g01 = ['2021-02-01 05:00:31', '2021-02-02 00:01:04', '2021-02-03 00:05:09', '2021-02-04 00:05:15', '2021-02-05 00:03:14', '2021-02-06 00:00:25', '2021-02-07 00:04:09', '2021-02-08 00:04:35', '2021-02-09 00:00:00', '2021-02-10 00:02:00', '2021-02-11 00:01:28', '2021-02-12 00:06:31', '2021-02-13 00:00:30', '2021-02-14 00:03:30', '2021-02-15 00:05:20', '2021-02-16 00:00:13', '2021-02-17 00:00:21', '2021-02-18 00:08:02', '2021-02-19 00:00:31', '2021-02-20 00:00:04', '2021-02-21 00:05:05', '2021-02-22 00:02:18', '2021-02-23 00:00:10', '2021-02-24 00:00:38', '2021-02-25 00:00:47', '2021-02-26 00:00:17', '2021-02-27 00:00:28', '2021-02-28 00:03:00']
g02 = [164, 158, 180, 200, 177, 112, 97, 237, 95, 178, 163, 78, 67, 65, 134, 93, 220, 74, 131, 172, 77, 102, 208, 109, 113, 208, 110, 101]
fig = plt.figure()
fig, ax1 = plt.subplots(1,1)
plt.yscale("log")
barlist1=ax1.bar(g01,g02)
for i in range(21):
barlist1[i].set_color('pink')
degrees = 70
plt.xticks(rotation=degrees)
plt.xlabel('period', fontsize=14, fontweight="bold")
plt.ylabel('rating values', fontsize=10, fontweight="bold")
While the linked duplicate does improve the alignment with ha='right', the labels will still be slightly off.
First note that the ticks/labels are correctly mapped, which you can see by using rotation=90 (left subplot):
plt.xticks(rotation=90)
If you use rotation=70 with ha='right', notice that the labels are still slightly shifted. This is because matplotlib uses the text's bounding box for alignment, not the text itself (center subplot):
plt.xticks(rotation=70, ha='right')
To tweak the labels more precisely, add a ScaledTranslation transform (right subplot):
from matplotlib.transforms import ScaledTranslation
offset = ScaledTranslation(xt=0.075, yt=0, scale_trans=fig.dpi_scale_trans)
for label in ax1.xaxis.get_majorticklabels():
label.set_transform(label.get_transform() + offset)

plotly column with vertical border and color for specific column

I am looking for a solution to set a vertical border and color for a specific column(s). for this example the column "Scores".
import plotly.graph_objects as go
import plotly
fig = go.Figure(data=[go.Table(
header=dict(values=['<b>Values', '<b>Scores', 'column'],
line_color='darkslategray',
#fill_color='lightskyblue',
align='center'),
cells=dict(values=[[100, 100, 100, 300], # 1st column
[90, 90, 90, 270],
[90, 90, 90, 270]], # 2nd column
line_color='darkslategray',
#fill_color='lightcyan',
align='center'))
])
fig.update_layout(width=250, height=130)
fig.update_layout(margin=dict(l=10, r=10, t=10, b=10))
fig.show()
the perfect solution I expect looks like the table (created with excel). if somebody only know how to color the column this also would help. Thanks!
As far as I know, you cannot change the color of individual ruled lines. The only settings for lines are line width and color. The color for each cell can be specified individually by column or by an array corresponding to the cell.
import plotly.graph_objects as go
import plotly
fig = go.Figure(data=[go.Table(
header=dict(values=['<b>Values', '<b>Scores', 'column'],
line_color=['white','mediumpurple','white'],
fill_color=['white','mediumpurple','white'],
align='center'),
cells=dict(values=[[100, 100, 100, 300], # 1st column
[90, 90, 90, 270],
[90, 90, 90, 270]], # 2nd column
line_color=['white','mediumpurple','white'],
fill_color=['white','mediumpurple','white'],
align='center'))
])
fig.update_layout(width=250, height=130)
fig.update_layout(margin=dict(l=10, r=10, t=10, b=10))
fig.show()

Plotly-Python: How to make a gapped y axis?

Courtesy to the original question for Plotly-R. The following will focus on Python.
Is it possible to create a plotly bar chart, e.g. any chart from the following website: plotly.com/r/bar-charts/ but with the gapped (broken) Y axis? An example from (ggplot2, I believe) attached below:
To my knowledge, plotly hasn't got any built-in functionality to do this. But it's still possible to make a figure that matches your image using subplots if you:
use make_subplots(rows=2, cols=1, vertical_spacing = <low>),
add the same traces to figure positions [1, 1] and [2, 1],
remove x-axis labels for [1, 1], and
adjust the y axes for figure positions [1, 1] and [2, 1] to respectively start and end with your desired cutoff values in a defined interval.
Plot:
Complete code:
# imports
import plotly.graph_objects as go
import plotly.express as px
import pandas as pd
from plotly.subplots import make_subplots
# data
df = pd.DataFrame({'years': [1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2012],
'China': [219, 146, 112, 127, 124, 180, 236,
207, 236, 263,350, 430, 474, 1526,
488, 537, 500, 439],
'Rest of world': [16, 13, 10, 11, 28, 37,
43, 55, 56, 88, 105, 156, 270,
299, 340, 403, 549, 1499]})
df.set_index('years', inplace = True)
# colors and cut-offs
colors = px.colors.qualitative.Plotly
cut_interval = [600, 1400]
# subplot setup
fig = make_subplots(rows=2, cols=1, vertical_spacing = 0.04)
fig.update_layout(title = "USA plastic scrap exports (...with some made-up values)")
# Traces for [2, 1]
# marker_color=colors[i] ensures that categories follow the same color cycle
for i, col in enumerate(df.columns):
fig.add_trace(go.Bar(x=df.index,
y=df[col],
name=col,
marker_color=colors[i],
legendgroup = col,
), row=2, col=1)
# Traces for [1, 1]
# Notice that showlegend = False.
# Since legendgroup = col the interactivity is
# taken care of in the previous for-loop.
for i, col in enumerate(df.columns):
fig.add_trace(go.Bar(x=df.index,
y=df[col],
name=col,
marker_color=colors[i],
legendgroup = col,
showlegend = False,
), row=1, col=1)
# Some aesthetical adjustments to layout
fig.update_yaxes(range=[cut_interval[1], max(df.max()*1.1)], row=1, col=1)
fig.update_xaxes(visible=False, row=1, col=1)
fig.update_yaxes(range=[0, cut_interval[0]], row=2, col=1)
fig.show()

Conditionally change background color of specific cells

I have a DataFrame and I can save it as a png file. But now I want to change the background color of specific cells who meet a certain condition.
Conditions:
Numbers who are 80 or higher must get a green background.
Numbers below 80 must get a red background.
All column names and index cells need a black background with a white text color.
The following posts came close to what I want but didn't provided with the answer I needed.
Post 1
Post 2
My code:
import matplotlib.pyplot as plt
from pandas.tools.plotting import table
import pandas as pd
#My dataframe
df = pd.DataFrame({
'Weeks' : [201605, 201606, 201607, 201608],
'Computer1' : [50, 77, 96, 100],
'Computer2' : [50, 79, 100, 80],
'Laptop1' : [75, 77, 96, 95],
'Laptop2' : [86, 77, 96, 40],
'Phone' : [99, 99, 44, 85],
'Phone2' : [93, 77, 96, 25],
'Phone3' : [94, 91, 96, 33]
})
df2 = df.set_index('Weeks') #Makes the column 'Weeks' the index.
#Make a png file out of an dataframe.
plt.figure(figsize=(9,3))
ax = plt.subplot(211, frame_on=False) # no visible frame
ax.xaxis.set_visible(False) # hide the x axis
ax.yaxis.set_visible(False) # hide the y axis
table(ax, df2, rowLabels=df2.index, colLabels=df2.columns, loc='center', cellColours=None)
plt.savefig('mytable.png') #save it as an png.
This is how it currently looks:
This is how I want it to look
you can do something like this:
colors = df2.applymap(lambda x: 'green' if x>= 80 else 'red').reset_index().drop(['Weeks'], axis=1)
tbl = table(ax, df2, loc='center',
cellColours=colors.as_matrix(),
colColours=['black']*len(colors.columns),
rowColours=['black']*len(colors))
Setting index's color:
[tbl._cells[row, -1]._text.set_color('white') for row in range(1, len(colors)+1)]
setting header's colors:
[tbl._cells[0, col]._text.set_color('white') for col in range(len(colors.columns))]
plt.show()
Code (complete):
import matplotlib.pyplot as plt
from pandas.tools.plotting import table
import pandas as pd
#My dataframe
df = pd.DataFrame({
'Weeks' : [201605, 201606, 201607, 201608],
'Computer1' : [50, 77, 96, 100],
'Computer2' : [50, 79, 100, 80],
'Laptop1' : [75, 77, 96, 95],
'Laptop2' : [86, 77, 96, 40],
'Phone' : [99, 99, 44, 85],
'Phone2' : [93, 77, 96, 25],
'Phone3' : [94, 91, 96, 33]
})
df2 = df.set_index('Weeks') #Makes the column 'Weeks' the index.
colors = df2.applymap(lambda x: 'green' if x>= 80 else 'red') \
.reset_index().drop(['Weeks'], axis=1)
#print(colors)
plt.figure(figsize=(10,5))
ax = plt.subplot(2, 1, 1, frame_on=True) # no visible frame
#ax.xaxis.set_visible(False) # hide the x axis
#ax.yaxis.set_visible(False) # hide the y axis
# hide all axises
ax.axis('off')
# http://matplotlib.org/api/pyplot_api.html?highlight=table#matplotlib.pyplot.table
tbl = table(ax, df2,
loc='center',
cellLoc='center',
cellColours=colors.as_matrix(),
colColours=['black']*len(colors.columns),
rowColours=['black']*len(colors),
#fontsize=14
)
# set color for index (X, -1) and headers (0, X)
for key, cell in tbl.get_celld().items():
if key[1] == -1 or key[0] == 0:
cell._text.set_color('white')
# remove grid lines
cell.set_linewidth(0)
# refresh table
plt.show()
# save it as an png.
plt.savefig('mytable.png')

Categories