eshangj/stackoverflow_q_and_a_sample huggingface dataset:
Question: I'm considering a data analysis project involving information on Japanese TV broadcasts. The relevant data will include broadcast times, and some of those will be for programs that aired late at night. Late-night Japanese TV schedules follow a non-standard time format called the 30-hour system (brief English explanation here). Most times are given in normal Japan Standard Time, formatted as %H:%M. Times from midnight to 6 AM, however, are treated as an extension of the previous day and numbered accordingly, under the logic that that's how people staying up late experience them. For example, Macross Frontier was broadcast in Kansai at 1:25 AM, but it was written as 25:25. I want to use this data in a Pandas or Polars DataFrame. Theoretically, it could be left as a string, but it'd be more useful to convert it to a standard format for datetimes -- either Python's built-in type, or the types used in NumPy or Polars. One simple approach could be: from datetime import date, time, datetime from zoneinfo import ZoneInfo def process_30hour(d: date, t: str): h, m = [int(n) for n in t.split(':')] # assumes format 'HH:MM' for t if h > 23: h -= 24 d += 1 return datetime.combine(d, time(h, m), ZoneInfo('Japan'))  This could then be applied to a whole DataFrame with DataFrame.apply(). There may be a more performant way, however, especially considering the vectorization features of DataFrames -- both libraries recommend avoiding DataFrame.apply() if there's an alternative.

Answer: IIUC, you could use create a datetime with '00:00' as time and add the hours as timedelta: from datetime import date, time, datetime, timedelta from zoneinfo import ZoneInfo def process_30hour(d: date, t: str): h, m = map(int, t.split(':')) # assumes format 'HH:MM' for t return (datetime.combine(d, time(), ZoneInfo('Japan')) + timedelta(hours=h, minutes=m)) process_30hour(date(2024, 12, 20), '25:25')  Output: datetime.datetime(2024, 12, 21, 1, 25, tzinfo=zoneinfo.ZoneInfo(key='Japan'))  The same logic can be used vectorially with pandas: df = pd.DataFrame({'date': ['2024-12-20 20:25', '2024-12-20 25:25']}) # split string tmp = df['date'].str.split(expand=True) # convert to datetime/timedelta, combine df['datetime'] = pd.to_datetime(tmp[0]) + pd.to_timedelta(tmp[1]+':00')  For fun, as a one-liner: df['datetime'] = (df['date'].add(':00') .str.split(expand=True) .astype({0: 'datetime64[ns]', 1: 'timedelta64[ns]'}) .sum(axis=1) )  Output:  date datetime 0 2024-12-20 20:25 2024-12-20 20:25:00 1 2024-12-20 25:25 2024-12-21 01:25:00
Question: I'm trying to connect to IG's lightstreamer server via python to obtain candle chart data. However, I always seem to get item updates every second even though I specify that I want it every minute or every hour. This is my code: from lightstreamer.client import * loggerProvider = ConsoleLoggerProvider(ConsoleLogLevel.WARN) LightstreamerClient.setLoggerProvider(loggerProvider) ls_client = LightstreamerClient("https://demo-apd.marketdatasystems.com", None) ls_client.connectionDetails.setUser("...") ls_client.connectionDetails.setPassword("...") ls_client.connect() subscription = Subscription( mode="MERGE", items=["CHART:CS.D.BITCOIN.CFD.IP:1MINUTE"], fields=["BID_CLOSE"]) subscription.addListener(SubListener()) ls_client.subscribe(subscription) input() ls_client.unsubscribe(subscription) ls_client.disconnect() class SubListener: def onItemUpdate(self, update): print(update.getValue("BID_CLOSE"))  The 1MINUTE part of CHART:CS.D.BITCOIN.CFD.IP:1MINUTE doesn't seem to affect anything. I've tried the same item string in IG's streaming companion and I'm able to obtain updates every minute that way, but it won't work in code for some reason. Any ideas?

Answer: I believe that the label 1MINUTE in the item name indicates the duration of the time interval for the chart's candlestick aggregation; however, the updates are sent continuously. If you want to receive updates at a specific frequency, you could leverage the setRequestedMaxFrequency option of the Lightstreamer client library. To receive one update per minute, you should use something like the following: subscription.setRequestedMaxFrequency(Decimal(1)/Decimal(60));
Question: I have the following pandas dataframe: # Create the DataFrame df = pd.DataFrame({ 'id': [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2], 'date': [1, 2, 3, 4, 5, 6, 7, 8, 5, 6, 7, 8, 9, 10, 11, 12], 'value': [11, 12, 13, 14, 15, 16, 17, 18, 21, 22, 23, 24, 25, 26, 27, 28] }) df id date value 0 1 1 11 1 1 2 12 2 1 3 13 3 1 4 14 4 1 5 15 5 1 6 16 6 1 7 17 7 1 8 18 8 2 5 21 9 2 6 22 10 2 7 23 11 2 8 24 12 2 9 25 13 2 10 26 14 2 11 27 15 2 12 28  I want to query the above dataframe, in a rolling window manner, for both ids. The rolling window should be of size n. So, if n==2, in the 1st iteration I would like to query this: df.query('(id==1 and (date==1 or date==2)) or (id==2 and (date==5 or date==6))') id date value 0 1 1 11 1 1 2 12 8 2 5 21 9 2 6 22  in the 2nd iteration I would like to query this: df.query('(id==1 and (date==2 or date==3)) or (id==2 and (date==6 or date==7))') id date value 1 1 2 12 2 1 3 13 9 2 6 22 10 2 7 23  in the 3rd iteration I would like to query this: df.query('(id==1 and (date==3 or date==4)) or (id==2 and (date==7 or date==8))') id date value 2 1 3 13 3 1 4 14 10 2 7 23 11 2 8 24  etc. How could I do that in pandas ? My data has around 500 ids

Answer: The exact expected logic is not fully clear, but assuming you want to loop over the groups/rolls, you could combine groupby.nth with sliding_window_view. By reusing the DataFrameGroupBy object, will only need to compute the groups once: import numpy as np from numpy.lib.stride_tricks import sliding_window_view as swv n = 2 max_size = df['id'].value_counts(sort=False).max() g = df.sort_values(by=['id', 'date']).groupby('id', sort=False) for idx in swv(np.arange(max_size), n): print(f'rows {idx}') print(g.nth(idx))  Output: rows [0 1] id date value 0 1 1 11 1 1 2 12 8 2 5 21 9 2 6 22 rows [1 2] id date value 1 1 2 12 2 1 3 13 9 2 6 22 10 2 7 23 rows [2 3] id date value 2 1 3 13 3 1 4 14 10 2 7 23 11 2 8 24 rows [3 4] id date value 3 1 4 14 4 1 5 15 11 2 8 24 12 2 9 25 rows [4 5] id date value 4 1 5 15 5 1 6 16 12 2 9 25 13 2 10 26 rows [5 6] id date value 5 1 6 16 6 1 7 17 13 2 10 26 14 2 11 27 rows [6 7] id date value 6 1 7 17 7 1 8 18 14 2 11 27 15 2 12 28  Alternatively, and assuming groups with an identical size and sorted by id/date, using shifted indexing: n = 2 ngroups = df['id'].nunique() for idx in swv(np.arange(len(df)).reshape(-1, ngroups, order='F'), n, axis=0): print(f'indices: {idx.ravel()}') print(df.iloc[idx.flat])  Output: indices: [0 1 8 9] id date value 0 1 1 11 1 1 2 12 8 2 5 21 9 2 6 22 indices: [ 1 2 9 10] id date value 1 1 2 12 2 1 3 13 9 2 6 22 10 2 7 23 indices: [ 2 3 10 11] id date value 2 1 3 13 3 1 4 14 10 2 7 23 11 2 8 24 indices: [ 3 4 11 12] id date value 3 1 4 14 4 1 5 15 11 2 8 24 12 2 9 25 indices: [ 4 5 12 13] id date value 4 1 5 15 5 1 6 16 12 2 9 25 13 2 10 26 indices: [ 5 6 13 14] id date value 5 1 6 16 6 1 7 17 13 2 10 26 14 2 11 27 indices: [ 6 7 14 15] id date value 6 1 7 17 7 1 8 18 14 2 11 27 15 2 12 28
Question: I am trying to set multiple elements in a Polars DataFrame based on a condition, similar to how it is done in Pandas. Here’s an example in Pandas: import pandas as pd df = pd.DataFrame(dict( A=[1, 2, 3, 4, 5], B=[0, 5, 9, 2, 10], )) df.loc[df['A'] < df['B'], 'A'] = [100, 210, 320] print(df)  This updates column A where A < B with [100, 210, 320]. In Polars, I know that updating a DataFrame in place is not possible, and it is fine to return a new DataFrame with the updated elements. I have tried the following methods: Attempt 1: Using Series.scatter with map_batches import polars as pl df = pl.DataFrame(dict( A=[1, 2, 3, 4, 5], B=[0, 5, 9, 2, 10], )) def set_elements(cols): a, b = cols return a.scatter((a < b).arg_true(), [100, 210, 320]) df = df.with_columns( pl.map_batches(['A', 'B'], set_elements) )  Attempt 2: Creating an update DataFrame and using update() df = df.with_row_index() df_update = df.filter(pl.col('A') < pl.col('B')).select( 'index', pl.Series('A', [100, 210, 320]) ) df = df.update(df_update, on='index').drop('index')  Both approaches work, but they feel cumbersome compared to the straightforward Pandas syntax. Question: Is there a simpler or more idiomatic way in Polars to set multiple elements conditionally in a column, similar to the Pandas loc syntax?

Answer: updated You can work around pl.Series.scatter() using pl.Expr.arg_true() or pl.arg_where(), although it would require accessing column as pl.Series: df.with_columns( df.get_column("A").scatter( # or df["A"].scatter df.select((pl.col.A < pl.col.B).arg_true()), # or df.select(pl.arg_where(pl.col.A < pl.col.B)), [100, 210, 320] ) )  shape: (5, 2) ┌─────┬─────┐ │ A ┆ B │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ 0 │ │ 100 ┆ 5 │ │ 210 ┆ 9 │ │ 4 ┆ 2 │ │ 320 ┆ 10 │ └─────┴─────┘  Or, using @Hericks answer you can inplace update it: df[df.select((pl.col.A < pl.col.B).arg_true()), "A"] = [100, 210, 320] # or df[df.select(pl.arg_where(pl.col.A < pl.col.B)), "A"] = [100, 210, 320]  shape: (5, 2) ┌─────┬─────┐ │ A ┆ B │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ 0 │ │ 100 ┆ 5 │ │ 210 ┆ 9 │ │ 4 ┆ 2 │ │ 320 ┆ 10 │ └─────┴─────┘  original I'd say the way @jqurious did it in this answer is probably as short as you can get. idxs = pl.when(pl.col.A < pl.col.B).then(1).cum_sum() - 1 new_values = pl.lit(pl.Series([100, 210, 320])) df.with_columns(A = pl.coalesce(new_values.get(idxs), 'A'))  shape: (5, 2) ┌─────┬─────┐ │ A ┆ B │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ 0 │ │ 100 ┆ 5 │ │ 210 ┆ 9 │ │ 4 ┆ 2 │ │ 320 ┆ 10 │ └─────┴─────┘
Question: I am making a function that takes length:int and distance:int as inputs, and output the largest integer that satisfies the following properties in its binary representation:  It starts with 1, ends with 1  There are distance - 1 many 0 between each 1  Its length is strictly less than length   It could be implemented as the following: def repeatdigit(length:int, distance:int) -> int: result = 0 pointer = 1 for _ in range(1, length, distance): result |= pointer pointer <<= distance return result  For example: repeatdigit(10,3)==0b1001001 , repeatdigit(15,4)=0b1000100010001. I’m only caring about binary because I need to use it as a tool of bit manipulation. In practice, length will be very big, distance ** 2 < length. Assuming the input is valid. As its name suggested, it is repeating a same pattern over and over. An explicit formula: result = (1 << (length+distance-2 - ((length-2) % distance)))//((1 << distance) - 1)  But both algorithm are slow, their time complexity is O(n²), where n = length. Doing similar things with list only takes O(n). Namely ([1]+[0]*(distance-1)) * ((length-2)//distance) + [1] (Context: I want to make such an integer so that I don’t need to store 0 and 1 in a very long list as it is space consuming) How do I make such an integer in O(n)?

Answer: Doubling the number of 1-bits instead of adding them just one at a time: def repeatdigit(length:int, distance:int) -> int: def f(want): if want == 1: return 1 have = (want + 1) // 2 x = f(have) add = min(have, want - have) return x | (x << (add * distance)) ones = 1 + (length - 2) // distance return f(ones)  My ones, want, have and add refer to numbers of 1-bits. The add = min(have, want - have) could be "simplified", as I either add have or have - 1 1-bits. It comes from this earlier, slightly less optimal version: def repeatdigit(length:int, distance:int) -> int: result = 1 want = 1 + (length-2) // distance have = 1 while have < want: add = min(have, want - have) result |= result << (add * distance) have += add return result
Question: I'm type hinting a large existing Python codebase, and in one part it sets a signal handler using signal.signal. The signal handler is a custom function defined in the codebase, so I need to type hint it myself. However, while I can guess based on the description of signal.signal that the first parameter is an integer, the second one is just described as "None or a frame object" in the documentation. I have no idea what a frame object is, but thankfully the aforementioned documentation links to a section called "Frame objects" and the inspect module documentation. However, after looking through both of these, I still don't really find any information about how to actually type hint a frame object, just information that might be useful to someone writing code that interacts with frame objects without typing it. So, what type do I use for frame object type hints in Python?

Answer: types.FrameType is what you are looking for.
Question: The default header color for DataFrames (render.DataGrid(), render.DataTable()) is a very light grey (probably gainsboro). If I switch an app to dark mode using and DataFrame the header becomes unreadable. Is there any way to make a dict to tell shiny what color to use for the color gainsboro or for a specific object, if I switch to dark mode? Here's an (not so minimal) MRE: from shiny import App, render, ui import polars as pl app_ui = ui.page_fillable( ui.layout_sidebar( ui.sidebar(ui.input_dark_mode()), ui.layout_columns( ui.card( ui.card_header("card_header1", style='background:gainsboro'), ui.output_data_frame("card1"), full_screen=True ), col_widths=12 ) ) ) def server(input, output, session): @output @render.data_frame def card1(): return render.DataGrid(pl.DataFrame({'a': ['a','b','c','d']}), filters=True) app = App(app_ui, server) 

Answer: We can supply an id to the input_dark_mode(), say id="mode". And then we can define css dynamically depending on input.mode() (which is either "light" or "dark") for the required selectors. Below is an example for the card header. Express from shiny.express import input, render, ui with ui.layout_sidebar(): with ui.sidebar(): ui.input_dark_mode(id="mode") with ui.layout_columns(): with ui.card(): ui.card_header("card_header1", id="card_header1") @render.ui def style(): color = "gainsboro" if input.mode() == "light" else "red" css = f"#card_header1 {{ background: {color} }}" return ui.tags.style(css)  Core from shiny import App, ui, reactive app_ui = ui.page_fillable( ui.layout_sidebar( ui.sidebar(ui.input_dark_mode(id="mode")), ui.layout_columns( ui.card( ui.card_header("card_header1", id="card_header1"), full_screen=True ), col_widths=12 ) ) ) def server(input, output, session): @reactive.effect @reactive.event(input.mode) def _(): ui.remove_ui("#header_color") # Remove any previously added style tag color = "gainsboro" if input.mode() == "light" else "red" css = f"#card_header1 {{ background: {color} }}" # Add the CSS to the head of the document if css: style = ui.tags.style(css, id="#header_color") ui.insert_ui(style, selector="head") app = App(app_ui, server)
Question: I've data about how my times people are sick in certain locations (location A and B) at certain times (index of dates). I need to divide each value by the population in that location (column) AND at that time (index), which references a separate dictionary. Eg dataframe: import pandas as pd data = [{'A': 1, 'B': 3}, {'A': 2, 'B': 20}, {'A': "Unk", 'B': 50}] df = pd.DataFrame(data, index=[pd.to_datetime("2019-12-31") , pd.to_datetime("2020-12-30") , pd.to_datetime("2020-12-31")]) Out: A B 2019-12-31 1 3 2020-12-30 2 20 2021-12-31 Unk 50  Population dictionary (location_year): dic = {"A_2019": 100, "B_2019": 200, "A_2020": 120, "B_2020": 150}  While it's not necessary to have the output in the same df, the output I'm trying to achieve would be:  A B A1 B1 2019-12-31 1 3 0.01 0.015 2020-12-30 2 20 0.017 0.133 2021-12-31 Unk 50 nan 0.333  I've tried lots of different approaches, but almost always get an unhashable type error. for col in df.columns: df[col + "1"] = df[col]/dic[col + "_" + df.index.strftime("%Y")] Out: `TypeError: unhashable type: 'Index  I guess I don't understand how pandas is parsing the df.index value to the dictionary(?). Can this be fixed, or is another approach necessary?

Answer: You can create a Series from your dictionary, then unstack to DataFrame, reindex/set_axis, perform your operation and join with add_suffix: def split(k): x, y = k.split('_') return (int(y), x) # ensure using NaNs for missing values, not strings df = df.replace('Unk', pd.NA).convert_dtypes() # reshape to match the original DataFrame tmp = (pd.Series({split(k): v for k, v in dic.items()}) .unstack() .reindex(df.index.year) # match years in df.index .set_axis(df.index) # restore full dates ) # divide, add_suffix, join out = df.join(df.div(tmp).add_suffix('1')) # or # out = df.join(tmp.rdiv(df), rsuffix='1')  Output:  A B A1 B1 2019-12-31 1 3 0.01 0.015 2020-12-30 2 20 0.016667 0.133333 2020-12-31 <NA> 50 <NA> 0.333333  Intermediate tmp:  A B 2019-12-31 100 200 2020-12-30 120 150 2020-12-31 120 150  Variant Here we rather create a tmp with only the years, and use an intermediate rename step to perform the alignment: def split(k): x, y = k.split('_') return (int(y), x) df = df.replace('Unk', pd.NA).convert_dtypes() tmp = (pd.Series({split(k): v for k, v in dic.items()}) .unstack() ) out = df.join(df.rename(lambda x: x.year).div(tmp) .add_suffix('1').set_axis(df.index) )  Intermediate tmp:  A B 2019 100 200 2020 120 150
Question: I'm trying to write into the Windows registry key "SOFTWARE/Microsoft/DirectX/UserGpuPreferences" using the Python winreg module. The name of the sub-key needs to be the python executable path, which contains backslashes. However when using winreg.SetValue(), this instead adds a tree of keys following the components of the path, instead of a single sub-key whose name contains backslashes. import winreg path = ['SOFTWARE', 'Microsoft', 'DirectX', 'UserGpuPreferences'] registry = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER) key = winreg.OpenKey(registry, '\\'.join(path), 0, winreg.KEY_WRITE) sub_key = sys.executable value = 'GpuPreference=2;' winreg.SetValue(key, sub_key, winreg.REG_SZ, value)  Also escaping the backslashes (sys.executable.replace('\\', '\\\\')) does not change it. Is there any way to insert such a registry value, using Python?

Answer: It works correctly with SetValueEx()
Question: Consider this directory structure: a-a | b | c | print.py  Basically a-a/b/c. and print.py inside that directory. The contents of print.py looks like as : def print_5(): print("5") def print_10(): print("10")  I want to import and use these functions into my current file at the level of a-a. Structure : ls a-a test.py  How do I do that? Inside test.py, I tried importing all the functions as : from a-a.b.c import f print_5()  And it gives error as SyntaxError: invalid syntax that I understand. So, I moved 'a-a' to 'a_a' and it started to give me ModuleNotFoundError: No module named 'a_a'. I know it can be a trivial thing, just not coming in place for me.

Answer: Assuming a-a is the root directory, you first need to update to a_a as you have already done. Python modules cannot contain -. You should also add an __init__.py in each directory to mark it as package that can be imported. Your directory structure should look like: a_a/ ├── __init__.py ├── b/ │ ├── __init__.py │ ├── c/ │ ├── __init__.py │ ├── print.py └── test.py  You also need to ensure that the parent directory of a_a is in your python path. You can either run your script from the parent directory or update the PYTHONPATH environment variable. Your test.py would import like this: from a_a.b.c.print import print_5, print_10
Question: Here is the sample code to generate a dataframe. import pandas as pd import numpy as np dates = pd.date_range("20241218", periods=9600,freq='1MIN') df = pd.DataFrame(np.random.randn(9600, 4), index=dates, columns=list("ABCD"))  I want to fill all the columns with -1 for time between 1:35 to 1:45 for all the dates. Similarly I want to fill all the columns with -2 for the exact time of 1:00 for all the dates. For all other time values, the columns need to be filled with zeros. Please suggest the way forward.

Answer: Try: df.loc[df.between_time('01:35', '01:45').index] = -1 df.loc[df.index.time == pd.Timestamp('01:00').time()] = -2  Output can be verified with the similar: print(df.between_time('1:35', '1:45').head(15) ) print(df.loc[df.index.time == pd.Timestamp('01:00').time()])
Question: In pyproject.toml we have a optional-dependencies for a windows package: [project.optional-dependencies] windows = [ "pywinpty>=2.0.14" ]  To install: # on windows pip install .[windows] # on linux/mac we use the enclosed pty pip install .  Is it possible so pip install . does this check automatic? Or uv pip install . (pywinpty is a rust package)

Answer: You can use PEP 496 – Environment Markers and PEP 508 – Dependency specification for Python Software Packages; they're usable in setup.py, setup.cfg, pyproject.toml, requirements.txt. In particular in pyproject.toml: [project] dependencies = [ "pywinpty>=2.0.14; sys_platform == 'win32'" ]
Question: I have the following code which generates a 3D plot. I am trying to label the plot lines, but they are not ending up where I expect them. import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np # Data names = [ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L" ] wins = [ [0, 14, 20, 24, 29, 33, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39], [0, 7, 13, 17, 23, 27, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30], [0, 5, 8, 11, 15, 16, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19], [0, 7, 11, 17, 20, 25, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29], [0, 9, 14, 22, 29, 36, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42], [0, 6, 10, 16, 20, 24, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29], [0, 7, 13, 20, 26, 31, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34], [0, 10, 13, 18, 24, 29, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33], [0, 5, 11, 13, 16, 21, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26], [0, 12, 15, 18, 21, 25, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30], [0, 9, 11, 12, 17, 20, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26], [0, 15, 20, 25, 27, 33, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37], ] weeks = [f"Week{i+1}" for i in range(18)] # X-axis categories (nb of weeks) # Convert names into numerical indices for the Y-axis x = np.arange(len(weeks)) # X-axis y = np.arange(len(names)) # Y-axis wins_array = np.array(wins) # wins accumulated per weeks and per names # Create a 3D plot fig = plt.figure(figsize=(18, 18)) ax = fig.add_subplot(111, projection='3d') # Plot each line and add labels for i, y_week in enumerate(y): ax.plot(x, wins_array[i], zs=y_week, zdir='x', label=weeks[i]) # Add shaded area below the line ax.bar(x, wins_array[i], zs=y_week, zdir='x', alpha=0.1) # Add labels directly on the curves for j, my_label in enumerate(wins_array[i]): ax.text(i, my_label, y_week, f"{my_label}", color="red", fontsize=8, ha="center") # Customize labels ax.set_zlabel('Wins') # Z-axis is wins ax.set_xticks(y) # X-ticks are names ax.set_xticklabels(names, rotation=45) # Name labels on X-axis ax.set_yticks(x) # Y-ticks are weeks ax.set_yticklabels(weeks) # Week labels on Y-axis plt.show()  This is the current result:  The result I am trying to achieve is something like this:  How do I fix my code to achieve my desired result?

Answer: It is easier to separate the drawing and the text annotation: # Plot each line for i, y_week in enumerate(y): ax.plot(x, wins_array[i], zs=y_week, zdir='x', label=weeks[i]) # Add shaded area below the line ax.bar(x, wins_array[i], zs=y_week, zdir='x', alpha=0.1) # Add labels directly on the curves for i in y: for j, k in zip(x, wins_array[i]): ax.text(i, j, k, f"{k}", color="red", fontsize=8, ha="center")