Plotly Dash | Remove minor ticks - python

Goal: Run example code and run example with and without minor ticks.
Plotly documentation has example code of a graph with minor ticks. Running the code fails.
import plotly.express as px
import pandas as pd
df = px.data.tips()
fig = px.scatter(df, x="total_bill", y="tip", color="sex")
fig.update_xaxes(minor=dict(ticklen=6, tickcolor="black", showgrid=True))
fig.update_yaxes(minor_ticks="inside")
fig.show()
Source - "Adding minor ticks"
Error:
(linechart) daniel#ubuntu-pcs:~/PycharmProjects/linechart$ python linechart/del.py
Traceback (most recent call last):
File "/home/daniel/PycharmProjects/linechart/linechart/del.py", line 8, in <module>
fig.update_xaxes(minor=dict(ticklen=6, tickcolor="black", showgrid=True))
File "/home/daniel/miniconda3/envs/linechart/lib/python3.9/site-packages/plotly/graph_objs/_figure.py", line 20166, in update_xaxes
obj.update(patch, overwrite=overwrite, **kwargs)
File "/home/daniel/miniconda3/envs/linechart/lib/python3.9/site-packages/plotly/basedatatypes.py", line 5082, in update
BaseFigure._perform_update(self, kwargs, overwrite=overwrite)
File "/home/daniel/miniconda3/envs/linechart/lib/python3.9/site-packages/plotly/basedatatypes.py", line 3877, in _perform_update
raise err
ValueError: Invalid property specified for object of type plotly.graph_objs.layout.XAxis: 'minor'
Did you mean "mirror"?
...
Bad property path:
minor
^^^^^

Remove all minor ticks:
fig.update_xaxes(dtick=1)
fig.update_yaxes(dtick=1)
However, this doesn't solve the documentation's code snippet.

Related

How to adapt this python script to apt installed matplotlib vs pip3 installed

I have a script (MWE supplied)
import matplotlib.pyplot as plt
import matplotlib
s_xLocs = [864]
s_yLocs = [357]
s_score = [0.33915146615180547]
sMax = 0.34704810474264386
for i in range(len(s_xLocs)):
plt.scatter(s_xLocs[i], s_yLocs[i], c=s_score[i], s=(20*(s_score[i]+1.5)**4), cmap="plasma", marker='.', vmin=0, vmax=sMax)
matplotlib.pyplot.close()
which was being used to generate some plots using matplotlib. On my dev machine, I used matplotlib installed via pip3. The script is now being used on some other machines managed by IT and limited to using the version of matplotlib installed via apt install python3-matplotlib. This has caused my script to fail, throwing the error
Traceback (most recent call last):
File "./heatmaps.py", line 9, in <module>
plt.scatter(s_xLocs[i], s_yLocs[i], c=s_score[i], s=(20*(s_score[i]+1.5)**4), cmap="plasma", marker='.', vmin=0, vmax=sMax)
File "/usr/lib/python3/dist-packages/matplotlib/pyplot.py", line 2836, in scatter
__ret = gca().scatter(
File "/usr/lib/python3/dist-packages/matplotlib/__init__.py", line 1601, in inner
return func(ax, *map(sanitize_sequence, args), **kwargs)
File "/usr/lib/python3/dist-packages/matplotlib/axes/_axes.py", line 4451, in scatter
self._parse_scatter_color_args(
File "/usr/lib/python3/dist-packages/matplotlib/axes/_axes.py", line 4264, in _parse_scatter_color_args
n_elem = c_array.shape[0]
IndexError: tuple index out of range
After reading this Q/A I was able to seemingly narrow down the issue to the colormap c argument. After also reading the documentation I also tried passing in the entire list of s_score with no indexing ala
plt.scatter(s_xLocs[i], s_yLocs[i], c=s_score, s=(20*(s_score[i]+1.5)**4), cmap="plasma", marker='.', vmin=0, vmax=sMax)
but that gave a different and more confusing (IMO) error:
...
ValueError: Invalid RGBA argument: 0.33915146615180547
During handling of the above exception, another exception occurred:
...
ValueError: 'c' argument has 1 elements, which is not acceptable for use with 'x' with size 1, 'y' with size 1.
I am hoping someone can provide a solution to this issue which will work with python3-matplotlib and perhaps also clarify the errors/what is different between the version installed with pip3 vs apt.
This could be occasioned because of different versions of matplotlib installed.
As the problem is with the c parameter, I suggest creating a pallet and then getting the color based on the float value:
import matplotlib.pyplot as plt
from matplotlib import cm
import matplotlib as mpl
s_xLocs = [864]
s_yLocs = [357]
s_score = [0.33915146615180547]
sMax = 0.34704810474264386
palette = cm.get_cmap('plasma')
norm = mpl.colors.Normalize(vmin=0, vmax=sMax)
for i in range(len(s_xLocs)):
color = palette(norm(s_score[i]))
plt.scatter(s_xLocs[i], s_yLocs[i], color=color, s=(20*(s_score[i]+1.5)**4), marker='.')
Another solution that did not break other functionality was to change plotting to this method:
import matplotlib.pyplot as plt
import matplotlib
s_xLocs = [864]
s_yLocs = [357]
s_score = [0.33915146615180547]
sMax = 0.34704810474264386
sSizes = [(20*(size+1.5)**4) for size in s_score]
plt.scatter(s_xLocs, s_yLocs, c=s_score, s=sSizes, cmap="plasma", marker='.', vmin=0, vmax=sMax)
plt.show()

generate px.line graph (graph in web browser window). pytohn, pycharm, kmeans, graph, plotly

I have a working code that makes perfectly working graph with command plt.plot(df, cs.predict(df), 'o'). Its the right outpu but I need to make that graph in web browser window.(my teacher wants it that way). I got another code and it works with this:
fig = px.line(new_dataset2, x='time', y="value", title='coffee-machine wattage')
fig.show()
Its a different .csv file but u get the idea, the graph looks like this:
the thing is it wont allow me to plot by px.line. Is there some way how to transform the plt.plot to plx.line?
I tried this:
fig = px.line(cs.predict(df), x='_time', y="_value", title='coffee-machine wattage',)
fig.show()
but it throws an error
"Traceback (most recent call last):
File "C:\Users\matus\PycharmProjects\fridge\cofeemashine-kmeans.py", line 28, in <module>
fig = px.line(cs.predict(df), x='_time', y="_value", title='coffee-machine wattage',)
File "C:\Users\matus\PycharmProjects\fridge\permut\lib\site-packages\plotly\express\_chart_types.py", line 264, in line
return make_figure(args=locals(), constructor=go.Scatter)
File "C:\Users\matus\PycharmProjects\fridge\permut\lib\site-packages\plotly\express\_core.py", line 1990, in make_figure
args = build_dataframe(args, constructor)
File "C:\Users\matus\PycharmProjects\fridge\permut\lib\site-packages\plotly\express\_core.py", line 1405, in build_dataframe
df_output, wide_id_vars = process_args_into_dataframe(
File "C:\Users\matus\PycharmProjects\fridge\permut\lib\site-packages\plotly\express\_core.py", line 1207, in process_args_into_dataframe
raise ValueError(err_msg)
ValueError: Value of 'x' is not the name of a column in 'data_frame'. Expected one of [0] but received: _time
Process finished with exit code 1
"
I will post my code, graph and part of my .csv file
import pandas as pd
from sklearn import cluster as cls
import matplotlib.pyplot as plt
import plotly.express as px
# Read the CSV file into a pandas DataFrame
df = pd.read_csv('coffee_machine_2022-11-22_09_22_influxdb_data.csv',header=0,usecols=['_time','_value'] )
print(df)
# Convert the _time column to a datetime type
df['_time'] = pd.to_datetime(df['_time'], format='%Y-%m-%dT%H:%M:%SZ')
# Set the index of the DataFrame to the _time column
df = df.set_index('_time')
# Print the resulting DataFrame
print(df)
# df.interpolate(method='linear') # not neccesary
cs = cls.KMeans(n_clusters=4)
cs.fit(df)
print(cs.predict([[1200]]))
plt.plot(df, cs.predict(df), 'o')
plt.show()
#below doesnt work
fig = px.line(cs.predict(df), x='_time', y="_value", title='coffee-machine wattage',)
fig.show()
This is that working graph I need to change
part of my .csv file:
result,table,_start,_stop,_time,_value,_field,_measurement,device
,0,2022-10-23T08:22:04.124457277Z,2022-11-22T08:22:04.124457277Z,2022-10-24T12:12:35Z,44.61,power,shellies,Shelly_Kitchen-C_CoffeMachine/relay/0
,0,2022-10-23T08:22:04.124457277Z,2022-11-22T08:22:04.124457277Z,2022-10-24T12:12:40Z,17.33,power,shellies,Shelly_Kitchen-C_CoffeMachine/relay/0
,0,2022-10-23T08:22:04.124457277Z,2022-11-22T08:22:04.124457277Z,2022-10-24T12:12:45Z,41.2,power,shellies,Shelly_Kitchen-C_CoffeMachine/relay/0
,0,2022-10-23T08:22:04.124457277Z,2022-11-22T08:22:04.124457277Z,2022-10-24T12:12:51Z,33.49,power,shellies,Shelly_Kitchen-C_CoffeMachine/relay/0
,0,2022-10-23T08:22:04.124457277Z,2022-11-22T08:22:04.124457277Z,2022-10-24T12:12:56Z,55.68,power,shellies,Shelly_Kitchen-C_CoffeMachine/relay/0
,0,2022-10-23T08:22:04.124457277Z,2022-11-22T08:22:04.124457277Z,2022-10-24T12:12:57Z,55.68,power,shellies,Shelly_Kitchen-C_CoffeMachine/relay/0
,0,2022-10-23T08:22:04.124457277Z,2022-11-22T08:22:04.124457277Z,2022-10-24T12:13:02Z,25.92,power,shellies,Shelly_Kitchen-C_CoffeMachine/relay/0
,0,2022-10-23T08:22:04.124457277Z,2022-11-22T08:22:04.124457277Z,2022-10-24T12:13:08Z,5.71,power,shellies,Shelly_Kitchen-C_CoffeMachine/relay/0
,0,2022-10-23T08:22:04.124457277Z,2022-11-22T08:22:04.124457277Z,2022-10-24T12:13:14Z,553.75,power,shellies,Shelly_Kitchen-C_CoffeMachine/relay/0
,0,2022-10-23T08:22:04.124457277Z,2022-11-22T08:22:04.124457277Z,2022-10-24T12:13:19Z,5.71,power,shellies,Shelly_Kitchen-C_CoffeMachine/relay/0
,0,2022-10-23T08:22:04.124457277Z,2022-11-22T08:22:04.124457277Z,2022-10-24T12:13:24Z,8.95,power,shellies,Shelly_Kitchen-C_CoffeMachine/relay/0
,0,2022-10-23T08:22:04.124457277Z,2022-11-22T08:22:04.124457277Z,2022-10-24T12:13:26Z,5.69,power,shellies,Shelly_Kitchen-C_CoffeMachine/relay/0
,0,2022-10-23T08:22:04.124457277Z,2022-11-22T08:22:04.124457277Z,2022-10-24T12:13:30Z,5.63,power,shellies,Shelly_Kitchen-C_CoffeMachine/relay/0

Creating subplots of combined image and histogram from multiple Seaborn_images

I'm trying to create a figure with three subplots of a combined raster image and histogram. I found a class called seaborn_image with a function (seaborn_image.imghist) to plot an image and show the corresponding raster. However, I would like to plot three of these next to each other, but this turned out harder than it seemed.
The class does have this method to create subplots, but this does not work for the imghist objects. This gives the following error:
Traceback (most recent call last):
File "/home/margot/Documents/code/plot_rasters.py", line 542, in <module>
isns.ImageGrid(imghist_col)
File "/home/margot/anaconda3/lib/python3.9/site-packages/seaborn_image/_grid.py", line 439, in __init__
self._map_img_to_grid()
File "/home/margot/anaconda3/lib/python3.9/site-packages/seaborn_image/_grid.py", line 496, in _map_img_to_grid
if _d.ndim > 2:
AttributeError: 'Figure' object has no attribute 'ndim'
<Figure size 1440x504 with 0 Axes>
I also looked into using the SeabornFig2Grid class from this issue, using the following code:
fig = plt.figure(figsize=(20,7))
fig.subplots_adjust(top=1)
fig.suptitle('Crop rasters', fontsize=18)
nrows = 1
ncols = 3
imghist_s1 = isns.imghist(test_S1[test_key], aspect=2.2, cmap=batlow, dx=10, units='m') # pixelsize =10m
imghist_ndvi = isns.imghist(test_NDVI[test_key], aspect=2.2, vmin=0.1, vmax=0.95, cmap=batlow, dx=10, units='m') # pixelsize =10m
imghist_bp = isns.imghist(test_BP[test_key]/1000, aspect=2.2, vmin=0.1, vmax=0.95, cmap=batlow, dx=10, units='m') # pixelsize =10m
gs = gridspec.GridSpec(nrows, ncols)
mg0 = SeabornFig2Grid(imghist_s1, fig, gs[0])
mg1 = SeabornFig2Grid(imghist_s1, fig, gs[1])
mg2 = SeabornFig2Grid(imghist_s1, fig, gs[2])
gs.tight_layout(fig)
plt.show()
But this gives me the same error as was posted in this issue. Unfortunately, the given solution does not work for the seaborn_image class.
If this is not possible, I could also combine the images and histograms myself and then plot them as subplots. But I haven't found any suitable way to do this yet.
Can anyone help with the errors or does anyone have a suggestion how to approach the problem?

Update Line2D properties from line on different axes in matplotlib

In matplotlib, the update_from method of a Line2D object can be used to copy properties from another line (see e.g. this answer). This is not working if the two lines live on different axes. The following code:
fig, (ax1, ax2) = plt.subplots(2, 1)
line1, = ax1.plot(range(10), "r.")
line2, = ax2.plot(*line1.get_xydata().T)
line2.update_from(line1)
raises
AttributeError: 'NoneType' object has no attribute 'extents'
while the traceback leaves me puzzled.
My questions are:
Why is this error raised?
How can I copy (all) Line2D properties of line1 to line2 instead?
EDIT
After a bit more testing I can say that the AttributeError above is for example raised in a Jupyter notebook session with the %matplotlib inline backend. With the %matplotlib notebook backend or in a regular Python script (e.g. with the "qt5agg" backend), the code passes without an error but line2 is "invisible" afterwards.
For completeness, the above image was created using (Anaconda) Python 3.7.9 and matplotlib 3.3.1 with:
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.use("qt5agg")
fig, (ax1, ax2) = plt.subplots(2, 1)
line1, = ax1.plot(range(10), "r.")
line2, = ax2.plot(*line1.get_xydata().T)
line2.update_from(line1)
plt.savefig("test.png")
The problem remains that I cannot copy the Line2D properties from line1 to line2.
EDIT 2
Throwing a plt.tight_layout() into the mix brings back the AttributeError.
EDIT 3
As requested in the comments, here is the traceback for the error I get with plt.tight_layout() (EDIT 2):
Traceback (most recent call last):
File "test.py", line 11, in <module>
plt.tight_layout()
File "/home/janjoswig/.pyenv/versions/miniconda3-4.7.12/envs/md379/lib/python3.7/site-packages/matplotlib/cbook/deprecation.py", line 451, in wrapper
return func(*args, **kwargs)
File "/home/janjoswig/.pyenv/versions/miniconda3-4.7.12/envs/md379/lib/python3.7/site-packages/matplotlib/pyplot.py", line 1490, in tight_layout
gcf().tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
File "/home/janjoswig/.pyenv/versions/miniconda3-4.7.12/envs/md379/lib/python3.7/site-packages/matplotlib/cbook/deprecation.py", line 411, in wrapper
return func(*inner_args, **inner_kwargs)
File "/home/janjoswig/.pyenv/versions/miniconda3-4.7.12/envs/md379/lib/python3.7/site-packages/matplotlib/figure.py", line 2615, in tight_layout
pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
File "/home/janjoswig/.pyenv/versions/miniconda3-4.7.12/envs/md379/lib/python3.7/site-packages/matplotlib/tight_layout.py", line 308, in get_tight_layout_figure
pad=pad, h_pad=h_pad, w_pad=w_pad)
File "/home/janjoswig/.pyenv/versions/miniconda3-4.7.12/envs/md379/lib/python3.7/site-packages/matplotlib/tight_layout.py", line 84, in auto_adjust_subplotpars
bb += [ax.get_tightbbox(renderer, for_layout_only=True)]
File "/home/janjoswig/.pyenv/versions/miniconda3-4.7.12/envs/md379/lib/python3.7/site-packages/matplotlib/axes/_base.py", line 4199, in get_tightbbox
if np.all(clip_extent.extents == axbbox.extents):
AttributeError: 'NoneType' object has no attribute 'extents'
It seems update_from updates too much, including the transformation and the clipbox. Maybe the error comes from the object being totally invisible after clipping to the wrong clipbox?
A workaround can be to save both before updating and setting them back:
from matplotlib import pyplot as plt
fig, (ax1, ax2) = plt.subplots(2, 1)
line1, = ax1.plot(range(10), "r.")
line2, = ax2.plot(*line1.get_xydata().T)
old_transform = line2.get_transform()
old_clipbox = line2.clipbox
line2.update_from(line1)
line2.set_transform(old_transform)
line2.clipbox = old_clipbox
plt.tight_layout()
plt.draw()

Plot a dataframe of times

Hi I want to use a dataframe of times which are in the format hh:mm as the xticks of a figure.
Just to represent what I'm doing I have:
import matplotlib.pyplot as plt
import pandas as pd
#locate series to plot
df = pd.read_excel('Excel_file', header=None)
df1 = df.iloc[71:128, 3]
df2 = df.iloc[71:128, 0]
#Plot df2 on the x-axis and df1 on the y-axis
plt.plot(df2, df1)
plt.xticks(df2)
plt.show()
which gives me the (full) error:
Traceback (most recent call last):
File "C:/Users/Alessio/PycharmProjects/PeakAutomation/graphs.py", line 14, in <module>
plt.xticks(df2)
File "C:\Users\Alessio\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\matplotlib\pyplot.py", line 1483, in xticks
locs = ax.set_xticks(ticks)
File "C:\Users\Alessio\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\matplotlib\cbook\deprecation.py", line 400, in wrapper
return func(*args, **kwargs)
File "C:\Users\Alessio\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\matplotlib\axes\_base.py", line 3306, in set_xticks
ret = self.xaxis.set_ticks(ticks, minor=minor)
File "C:\Users\Alessio\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\matplotlib\cbook\deprecation.py", line 400, in wrapper
return func(*args, **kwargs)
File "C:\Users\Alessio\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\matplotlib\axis.py", line 1765, in set_ticks
self.set_view_interval(min(ticks), max(ticks))
File "C:\Users\Alessio\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\matplotlib\axis.py", line 1902, in setter
setter(self, min(vmin, vmax, oldmin), max(vmin, vmax, oldmax),
TypeError: '<' not supported between instances of 'float' and 'datetime.time'
How can I plot df2 as the x-axis values?
When I dont try to change the xticks, I get this:
Which is fine, but I want to have the x-values to be those from the dataFrame (df2)
Thanks

Categories