I'm using Python (beginner) and I want to plot the Bitcoin price in log scale but without seeing the log price, I want to see the linear price.
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from cryptocmd import CmcScraper
from math import e
from matplotlib.ticker import ScalarFormatter
# -------------IMPORT THE DATA----------------
btc_data = CmcScraper("BTC", "28-04-2012", "27-11-2022", True, True, "USD")
# Create a Dataframe
df = btc_data.get_dataframe()
#Set the index as Date instead of numerical value
df = df.set_index(pd.DatetimeIndex(df["Date"].values))
df
#Plot the Data
plt.style.use('fivethirtyeight')
plt.figure(figsize =(20, 10))
plt.title("Bitcoin Price", fontsize=18)
plt.yscale("log")
plt.plot(df["Close"])
plt.xlabel("Date", fontsize=15)
plt.ylabel("Price", fontsize=15)
plt.show()
My output
As you can see we have log scale price but I want to see "100 - 1 000 - 10 000" instead of "10^2 - 10^3 - 10^4" on the y axis.
Does anyone know how to solve this?
Have a nice day!
Welcome to Stackoverflow!
You were getting there, the following code will yield what you want (I simply added some fake data + 1 line of code to your plotting code):
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
y = [10**x for x in np.arange(0, 5, 0.1)]
x = [x for x in np.linspace(2018, 2023, len(y))]
#Plot the Data
plt.style.use('fivethirtyeight')
plt.figure(figsize =(20, 10))
plt.title("Bitcoin Price", fontsize=18)
plt.yscale("log")
plt.plot(x, y)
plt.xlabel("Date", fontsize=15)
plt.ylabel("Price", fontsize=15)
plt.gca().get_yaxis().set_major_formatter(ticker.ScalarFormatter())
plt.show()
This generates the following figure:
The fundamental lines are these:
import matplotlib.ticker as ticker
plt.gca().get_yaxis().set_major_formatter(ticker.ScalarFormatter())
Explanation: plt.gca() gets the currently active axis object. This object is the one we want to adapt. And the actual thing we want to adapt is the way our ticks get formatted for our y axis. Hence the latter part: .get_yaxis().set_major_formatter(). Now, we only need to choose which formatter. I chose ScalarFormatter, which is the default for scalars. More info on your choices can be found here.
Hope this helps!
Related
I plotted some values from my experiment output by the spider(anaconda). I want to change x axis scientific notation from 1e-05 to 1e-06. I googled and could not find a relevant solution to this problem. please help
enter code here
#Import Libraries
import numpy as np
import csv
import matplotlib.pyplot as plt
import pylab
import style
#Handling value error
def isfloat(num):
try:
float(num)
return True
except ValueError:
return False
#import csv file
with open( 'try1.csv', 'r') as i:
file01= list(csv.reader(i,delimiter=','))[2:]
file02=[[float(k) if (isfloat(k)) else 0 for k in j] for j in file01] # Picking the values only
#creating a mumpy array
Data= np.array(file02, dtype=float)
xdata= Data[:,0][::280]
ydata= Data[:,1][::280]
#Plot
plt.figure(1,dpi=800)
plt.title('Force Spectroscopy')
plt.ylabel('Vertical Deflection')
plt.xlabel('Measured Height')
plt.style.use(['seaborn_grid'])
plt.plot(xdata,ydata, color='green',label=('Experimental data'))
#Theoritical Plot
new= -(0.107e-5)*xdata
plt.plot(xdata,new, color= 'purple',label='Theoritical')
#Legend Modification
plt.legend('upper right',fontsize=20)
plt.legend()
Output image of my plot. see the axis notation 1e-5
you can use ticklabel_format() to set the tick label format. You can add the following line -> plt.ticklabel_format(style='sci', axis='x', scilimits=(-6,-6)) to your code to have the x-axis in e-06. Note that the -6 to -6 is telling matplotlib to set the format from e-06 to e-06. More info here
Your modified code sample here to demonstrate the same...
Code
import numpy as np
import matplotlib.pyplot as plt
import pylab
import style
xdata = np.array([1.21, 1.32, 2.54]) * (1e-5)
ydata = [1, 4, 15]
#Plot
plt.figure(1,dpi=800)
plt.title('Force Spectroscopy')
plt.ylabel('Vertical Deflection')
plt.xlabel('Measured Height')
plt.plot(xdata,ydata, color='green',label=('Experimental data'))
#Theoritical Plot
new= -(0.107e-5)*np.array(xdata)
plt.plot(xdata,new, color= 'purple',label='Theoritical')
plt.ticklabel_format(style='sci', axis='x', scilimits=(-6,-6))
#Legend Modification
plt.legend('upper right',fontsize=20)
plt.legend()
Output
I have a dataframe and I want to show them on graph. When I start my code, the x and y axis are non-sequential. How can I solve it? Also I give a example graph on picture. First image is mine, the second one is what I want.
This is my code:
from datetime import timedelta, date
import datetime as dt #date analyse
import matplotlib.pyplot as plt
import pandas as pd #read file
def daterange(date1, date2):
for n in range(int ((date2 - date1).days)+1):
yield date1 + timedelta(n)
tarih="01-01-2021"
tarih2="20-06-2021"
start=dt.datetime.strptime(tarih, '%d-%m-%Y')
end=dt.datetime.strptime(tarih2, '%d-%m-%Y')
fg=pd.DataFrame()
liste=[]
tarih=[]
for dt in daterange(start, end):
dates=dt.strftime("%d-%m-%Y")
with open("fng_value.txt", "r") as filestream:
for line in filestream:
date = line.split(",")[0]
if dates == date:
fng_value=line.split(",")[1]
liste.append(fng_value)
tarih.append(dates)
fg['date']=tarih
fg['fg_value']=liste
print(fg.head())
plt.subplots(figsize=(20, 10))
plt.plot(fg.date,fg.fg_value)
plt.title('Fear&Greed Index')
plt.ylabel('Fear&Greed Data')
plt.xlabel('Date')
plt.show()
This is my graph:
This is the graph that I want:
Line plot with datetime x axis
So it appears this code is opening a text file, adding values to either a list of dates or a list of values, and then making a pandas dataframe with those lists. Finally, it plots the date vs values with a line plot.
A few changes should help your graph look a lot better. A lot of this is very basic, and I'd recommend reviewing some matplotlib tutorials. The Real Python tutorial is a good starting place in my opinion.
Fix the y axis limit:
plt.set_ylim(0, 100)
Use a x axis locator from mdates to find better spaced x label locations, it depends on your time range, but I made some data and used day locator.
import matplotlib.dates as mdates
plt.xaxis.set_major_locator(mdates.DayLocator())
Use a scatter plot to add data points as on the linked graph
plt.scatter(x, y ... )
Add a grid
plt.grid(axis='both', color='gray', alpha=0.5)
Rotate the x tick labels
plt.tick_params(axis='x', rotation=45)
I simulated some data and plotted it to look like the plot you linked, this may be helpful for you to work from.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import matplotlib.dates as mdates
fig, ax = plt.subplots(figsize=(15,5))
x = pd.date_range(start='june 26th 2021', end='july 25th 2021')
rng = np.random.default_rng()
y = rng.integers(low=15, high=25, size=len(x))
ax.plot(x, y, color='gray', linewidth=2)
ax.scatter(x, y, color='gray')
ax.set_ylim(0,100)
ax.grid(axis='both', color='gray', alpha=0.5)
ax.set_yticks(np.arange(0,101, 10))
ax.xaxis.set_major_locator(mdates.DayLocator())
ax.tick_params(axis='x', rotation=45)
ax.set_xlim(min(x), max(x))
I'm trying to make the labels of my graph correlate to the months column of a CSV file I've made, however when the program is run the graph prints perfectly but the months do not show on the x axis, just numbers. How do I fix this?
EDIT: The error it gives me is "ConversionError: Failed to convert value(s) to axis units"
My code:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
crimedata = pd.read_csv('MasterFileCSV.csv')
homicide = crimedata['Homicide Convictions'].values
robbery = crimedata['Robbery Convictions'].values
crimDamage = crimedata['Criminal Damage Convictions'].values
month = crimedata['month'].values
fig = plt.figure()
plt.xticks(month, rotation='vertical')
plt.plot(np.arange(len(homicide)), homicide, color='red', label='Homicide Convictions')
plt.plot(np.arange(len(robbery)), robbery, color='green', label='Robbery Convictions')
plt.plot(np.arange(len(crimDamage)), crimDamage, color='blue', label='Criminal Damage Convictions')
plt.legend(loc='best')
plt.show()
I got these 2 simple csv data but when plotting the 'mon' line gone strange toward the end.
When plotting one chart, it is fine but when the 2 charts plotted together the 'monarch' one goes strange.
Thanks in advance.
Here is the code
import pandas as pd
from matplotlib import pyplot as plt
def run_plot1():
df_ash = pd.read_csv('./data/ashburn.csv')
df_mon = pd.read_csv('./data/monarch1bed.csv')
plt.grid(True)
plt.plot(df_ash['Date'], df_ash['Ash1bed'], label='Ashburn 1 bed')
plt.plot(df_mon['Date'], df_mon['Mon1bed'], label='Monarch 1 bed')
plt.xlabel("Date")
plt.ylabel("Rate")
plt.style.use("fivethirtyeight")
plt.title("One Bed Comparison")
plt.legend()
plt.savefig('data/sample.png')
plt.tight_layout()
plt.show()
run_plot1()
and the csv datas:
Date,Ash1bed,Ash2bed,Ash3bed
08-01,306,402
22-01,181,286,349
05-02,176,281,336
19-02,188,293,369
04-03,201,306,402
18-03,209
01-04,217,394,492
15-04,209,354,455
29-04,197,302,387
13-05,205,326,414
27-05,217,362,473
10-06,390,532
08-07,415
22-07,415
05-08,415
19-08,415
15-09,290,452,594
and another :
Date,Mon1bed
08-01,230
05-02,160
19-02,160
04-03,190
18-03,190
01-04,260
15-04,260
29-04,260
13-05,300
27-05,330
10-06,330
24-06,350
08-07,350
22-07,350
05-08,350
19-08,350
02-09,350
The basic reason of erratic printout is that your Date columns
in both DataFrames are of string type.
Convert them to datetime:
df_ash.Date = pd.to_datetime(df_ash.Date, format='%d-%m')
df_mon.Date = pd.to_datetime(df_mon.Date, format='%d-%m')
But to have "reader friendly" X-axis labels, a number of additional
steps are required.
Start from necessary imports:
from pandas.plotting import register_matplotlib_converters
import matplotlib.dates as mdates
Then register matplotlib converters:
register_matplotlib_converters()
And to get proper printout, run:
fig, ax = plt.subplots() # figsize=(10, 6)
ax.grid(True)
ax.plot(df_ash['Date'], df_ash['Ash1bed'], label='Ashburn 1 bed')
ax.plot(df_mon['Date'], df_mon['Mon1bed'], label='Monarch 1 bed')
plt.xlabel("Date")
plt.ylabel("Rate")
plt.style.use("fivethirtyeight")
plt.title("One Bed Comparison")
plt.legend()
dm_fmt = mdates.DateFormatter('%d-%m')
ax.xaxis.set_major_formatter(dm_fmt)
plt.xticks(rotation=45);
For your data I got:
You should convert the date variable to a date format
df1.Date = pd.to_datetime(df1.Date, format='%d-%m')
df2.Date = pd.to_datetime(df2.Date, format='%d-%m')
plt.plot(df1.Date, df1.Ash1bed)
plt.plot(df2.Date, df2.Mon1bed)
I want to set the x tick density by specifying how many ticks to skip each time. For example, if the x axis is labelled by 100 consecutive dates, and I want to skip every 10 dates, then I will do something like
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
ts = pd.period_range("20060101", periods=100).strftime("%Y%m%d")
y = np.random.randn(100)
ax = plt.subplot(1, 1, 1)
ax.plot(ts, y)
xticks = ax.get_xticks()
ax.set_xticks(xticks[::10])
plt.xticks(rotation="vertical")
plt.show()
However the output is out of place. Pyplot only picks the first few ticks and place them all in the wrong positions, although the spacing is correct:
What can I do to get the desired output? Namely the ticks should be instead:
['20060101' '20060111' '20060121' '20060131' '20060210' '20060220'
'20060302' '20060312' '20060322' '20060401']
#klim's answer seems to put the correct marks on the axis, but the labels still won't show. An example where the date axis is correctly marked yet without labels:
Set xticklabels also. Like this.
xticks = ax.get_xticks()
xticklabels = ax.get_xticklabels()
ax.set_xticks(xticks[::10])
ax.set_xticklabels(xticklabels[::10], rotation=90)
Forget the above, which doesn't work.
How about this?
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
ts = pd.period_range("20060101", periods=100).strftime("%Y%m%d")
x = np.arange(len(ts))
y = np.random.randn(100)
ax = plt.subplot(1, 1, 1)
ax.plot(x, y)
ax.set_xticks(x[::10])
ax.set_xticklabels(ts[::10], rotation="vertical")
plt.show()
This works on my machine.