-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plotting DataFrame with timedelta64 (y-axis) #801
Comments
Is there any progress regarding this, I really need to use timedelta64 on Y-axis? |
That's really not much of a workaround. Showing Jan 1, 1970 at the bottom... Timedelta is really a standard feature used all the time and plots with the y-axis being timedelta are very common. |
Hey, it's a bit late to the party. But, I wrote a solution for this issue. You can have dash, including its iterative features working and a datetime format in any sense. This, includes the autorender to solve for many x_sample points, so that it won't crash your axis. Such is the following: For the x_axis make absolutely sure that the format of your list is list[str] and they are consistent. ALSO, match the format in those strings in the tickformat of your list, the reference for time is standard as used in datetime objects, for future reference check: https://plotly.com/python/reference/layout/xaxis/#layout-xaxis-tickformat e.g.:
mock_list to be the x values in a scatter plot for instance
|
Thanks @ThomasGl. However, this works only for the last subplot in the figure. The X axis is displayed in Tried for xaxis in range(1, 4):
fig['layout'][f'xaxis{xaxis}']['tickformat'] = "%H:%M:%S.%f" with no help. |
Hi. Ill take at look at it over the weekend, but can you share a bit more of information upon the issue you are having? |
@dizcza also take note that you must adjust the axis for each subplot. As the engine responsible to generate the graphs renders each one as a new "fig" object with defaults params |
Here is the code I'm using: import plotly.graph_objects as go
from plotly.subplots import make_subplots
def add_traces(fig, record_data_dict: dict):
# only one key/value for now in this dict
for sensor, record_data in record_data_dict.items():
y = np.random.randn(1000, 3)
# convert s to ms
time_ms = (record_data.time * 1000).astype(np.int32)
td = pd.to_timedelta(time_ms, unit='ms') + pd.Timestamp("1970/01/01")
idx = np.arange(len(y)).astype(str)
for dim in range(3):
trace = go.Scatter(
x=td,
y=y[:, dim],
hovertext=idx,
name="AAA",
legendgroup=sensor,
showlegend=dim == 0,
marker=dict(color=colors[sensor]),
line=dict(color=colors[sensor]),
opacity=0.8
)
fig.add_trace(trace, row=dim + 1, col=1)
def plot_fig(record_dir=DATA_DIR / "2023.02.28"):
fig = make_subplots(rows=3, shared_xaxes=True)
record = Record(record_dir)
add_traces(fig, record.data)
fig['layout']['xaxis3']['title'] = "Time, s"
fig.update_layout(
title=record_dir.name,
legend_title="Sensor",
)
fig.update_xaxes(tickformat="%H:%M:%S.%f") The 1st and 2nd plots hover data is incorrect: it starts with |
How can I do so? In my case, I have only one figure. |
Each subplot renders the engine plot for figure, in the sense that you have as many fig objects as you have subplots, thus in your case you have 4 fig objects, One containing subplots and then 3 as you have 3 subplots. As for starting in Jan 1, 1970. this is a standard initial date, in case of missing compiling data, meaning, if you don't have a "DD:MM:YYYY" string like in the element responsible to render it, check in the documentation for the dash plots in case it changed, or it has some slightly different format. This could be generated using a list comprehension. Yet, as for correcting timestamp, pass the line with By the way, I can't know if theres an error with your data without the the function call arg to plot_fig, by that I mean that I need whatever DATA_DIR contains in order to recreate your plots |
All right, here is fully reproducible code: import numpy as np
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
def add_traces(fig):
# only one key/value for now in this dict
y = np.random.randn(1000, 3)
time_s = np.random.rand(len(y)).cumsum()
time_ms = (time_s * 1000).astype(np.int32)
td = pd.to_timedelta(time_ms, unit='ms') + pd.Timestamp("1970/01/01")
idx = np.arange(len(y)).astype(str)
for dim in range(3):
trace = go.Scatter(
x=td,
y=y[:, dim],
hovertext=idx,
name="AAA",
showlegend=dim == 0,
opacity=0.8
)
fig.add_trace(trace, row=dim + 1, col=1)
def plot_fig():
fig = make_subplots(rows=3, shared_xaxes=True)
add_traces(fig)
fig['layout']['xaxis3']['title'] = "Time, s"
fig.update_xaxes(tickformat="%H:%M:%S.%f")
fig.show()
if __name__ == '__main__':
plot_fig()
I understand that this is the standard initial date. But showing the date while hovering is not expected. I expect to have both the X axis and hover-on-data X values formatted to the
Tried with no luck. |
Just try running this example and hover on the 1st, 2nd, and 3rd subplots, and you'll see the difference. |
I see, you only desire the xaxes in the "%H:%M:%S" to show up? Ill run it tomorrow night |
Correct. Not only the X axis (the bottom panel) but also X values when I hover the mouse over any subplot. |
import numpy as np def add_traces(fig): def plot_fig(): if name == 'main': |
@dizcza I am pretty sure this is what you were looking for? I didn't quite understand why you were adding pd.Timestamp("1970/01/01"), and be aware of the dash expect type for this operation to work.... it needs a List[str] object, where the string are already formatted.... e.g. for a "03:45:10" its expected a "%H:%M:%S" |
@ThomasGl thanks this is promising but the X axis labeling looks weird and not so intuitive in my original example. I mean it's much easier to look at
Because if I don't, I'm getting this: Just like the author of this issue reported. And he added Thanks for the effort though. I'm not sure which version I'll use: with "1970/01/01" upfront obfuscating the users or confusing X axis string labeling for each point. |
Hmmm. I mean yes it does look overcrowded a bit. Bit its because of the densuty of your data. When and if you zoom in you would see it fits better, again I suggest you look in the plotly documentation for the function behavior of Yet I hope I helped you understand a bit more and that you can carry on from here |
The core challenge here is that Plotly's date/time axes can only today represent specific absolute instants in time (e.g. March 5, 2023 at 8:13am UTC), and hence are incompatible with relative We are aware of these limitations in the library and would certainly undertake the development required to add relative time axes to the underlying Plotly.js library, but this would require external sponsorship. |
If you are mostly concerned with the hoverlabel, you can use the following single line to set the |
Thanks @nicolaskruchten, I had trouble with hovertemplate language in the past that's why I had been avoiding templates till you showed me how to use them, and your solution works like a charm. With these two hacks in mind, adding |
@juandering td = pd.to_timedelta(time_ms, unit='ms') + pd.Timestamp("1970/01/01")
trace = go.Scatter(x=td, y=...)
fig = make_subplots(rows=3, shared_xaxes=True, vertical_spacing=0.03)
fig.add_trace(trace, row=1, col=1)
fig.update_xaxes(tickformat="%H:%M:%S.%f")
hovertemplate = "%{x|%H:%M:%S.%f}, %{y}<br>point=%{hovertext}"
fig.update_traces(hovertemplate=hovertemplate) |
Many thanks @dizcza. |
Similar to #799 but on y-axis and pandas-dev/pandas#16953
displays
y-axis values are not correctly displayed
The text was updated successfully, but these errors were encountered: