eshangj/stackoverflow_q_and_a_sample huggingface dataset:
Question: I have a dataset where I would like to convert specific field names to values while performing a de aggregation the values into their own unique rows as well as perform a long pivot. Data Start Date End Area Final Type Middle Stat Low Stat High Stat Middle Stat1 Low Stat1 High Stat1 8/1/2013 9/1/2013 10/1/2013 NY 3/1/2023 CC 226 20 10 0 0 0 8/1/2013 9/1/2013 10/1/2013 CA 3/1/2023 AA 130 50 0 0 0 0 data = { "Start": ['8/1/2013', '8/1/2013'], "Date": ['9/1/2013', '9/1/2013'], "End": ['10/1/2013', '10/1/2013'], "Area": ['NY', 'CA'], "Final": ['3/1/2023', '3/1/2023'], "Type": ['CC', 'AA'], "Middle Stat": [226, 130], "Low Stat": [20, 50], "High Stat": [10, 0], "Middle Stat1": [0, 0], "Low Stat1": [0, 0], "High Stat1": [0, 0] }  Desired Start Date End Area Final Type Stat Range Stat1 8/1/2013 9/1/2013 10/1/2013 NY 3/1/2023 CC 20 Low 0 8/1/2013 9/1/2013 10/1/2013 CA 3/1/2023 AA 50 Low 0 8/1/2013 9/1/2013 10/1/2013 NY 3/1/2023 CC 226 Middle 0 8/1/2013 9/1/2013 10/1/2013 CA 3/1/2023 AA 130 Middle 0 8/1/2013 9/1/2013 10/1/2013 NY 3/1/2023 CC 10 High 0 8/1/2013 9/1/2013 10/1/2013 CA 3/1/2023 AA 0 High 0  Doing I believe I have to inject some sort of wide to long method, (SO member assisted) however unsure how to incorporate this whilst having the same suffix in the targeted (columns of interest) column names. pd.wide_to_long(df, stubnames=['Low','Middle','High'], i=['Start','Date','End','Area','Final'], j='', sep=' ', suffix='(stat)' ).unstack(level=-1, fill_value=0).stack(level=0).reset_index()  Any suggestion is appreciated. #Original Dataset import pandas as pd # create DataFrame data = {'Start': ['9/1/2013', '10/1/2013', '11/1/2013', '12/1/2013'], 'Date': ['10/1/2016', '11/1/2016', '12/1/2016', '1/1/2017'], 'End': ['11/1/2016', '12/1/2016', '1/1/2017', '2/1/2017'], 'Area': ['NY', 'NY', 'NY', 'NY'], 'Final': ['3/1/2023', '3/1/2023', '3/1/2023', '3/1/2023'], 'Type': ['CC', 'CC', 'CC', 'CC'], 'Low Stat': ['', '', '', ''], 'Low Stat1': ['', '', '', ''], 'Middle Stat': ['0', '0', '0', '0'], 'Middle Stat1': ['0', '0', '0', '0'], 'Re': ['','','',''], 'Set': ['0', '0', '0', '0'], 'Set2': ['0', '0', '0', '0'], 'Set3': ['0', '0', '0', '0'], 'High Stat': ['', '', '', ''], 'High Stat1': ['', '', '', '']} df = pd.DataFrame(data) 

Answer: One option is with pivot_longer from pyjanitor - in this case we use the special placeholder .value to identify the parts of the column that we want to remain as headers, while the rest get collated into a new column : # pip install pyjanitor import pandas as pd import janitor (df .pivot_longer( index = slice('Start', 'Type'), names_to = ("Range", ".value"), names_sep = " ") ) Start Date End Area Final Type Range Stat Stat1 0 8/1/2013 9/1/2013 10/1/2013 NY 3/1/2023 CC Middle 226 0 1 8/1/2013 9/1/2013 10/1/2013 CA 3/1/2023 AA Middle 130 0 2 8/1/2013 9/1/2013 10/1/2013 NY 3/1/2023 CC Low 20 0 3 8/1/2013 9/1/2013 10/1/2013 CA 3/1/2023 AA Low 50 0 4 8/1/2013 9/1/2013 10/1/2013 NY 3/1/2023 CC High 10 0 5 8/1/2013 9/1/2013 10/1/2013 CA 3/1/2023 AA High 0 0
Question: I'm originally an Ubuntu user, but I have to use a Windows Virtual Machine for some reason. I was trying to pip-install a package using the CMD, however, I'm getting the following error: from pip._vendor.packaging.utils import canonicalize_name ValueError: source code string cannot contain null bytes  I used pip install numpy and pip3 install numpy along with other commands I found while tying to fix the problem. I checked that pip is available and reinstalled Python to make sure the path is added. I've also made sure that I'm running everything as an administrator. Everything seems to be installed properly, but I keep getting that error. I've also checked almost all other StackOverflow questions related to this error message. How can I solve this?

Answer: The error that occurred was while using "Python 3.10.11 (64-bit)". Though I reinstalled it the issue continued. When I downgraded to "Python 3.9.0 (64-bit)", the issue was solved.
Question: I used Metaflow to load a Dataframe. It was successfully unpickled from the artifact store, but when I try to view its index using df.index, I get an error that says ModuleNotFoundError: No module named 'pandas.core.indexes.numeric'. Why? I've looked at other answers with similar error messages here and here, which say that this is caused by trying to unpickle a dataframe with older versions of Pandas. However, my error is slightly different, and it is not fixed by upgrading Pandas (pip install pandas -U).

Answer: This issue is caused by the new Pandas 2.0.0 release breaking backwards compatibility with Pandas 1.x, although I don't see this documented in the release notes. The solution is to downgrade pandas to the 1.x series: pip install "pandas<2.0.0"
Question: I would like to make simple calculations on a rolling basis, but have heavy performance issues when I try to solve this with a nested for-loop. I need to perform this kind of operations on very large data, but have to use standard Python (incl. Pandas). The values are floats and can be negative, zero or positive. I have a pd.DataFrame (df1) which contains (structured by some dimensions, lets call them key1 and key2) a start column, a end column and some operations-columns in between, which are supposed to be used to calculate the end column based on the start column. Basically, the simple logic is: start + plus - minus = end, where the end value of each row is the start value of the next row. This would need to be done by the two keys, i.e. for AX, AY and BX seperately. df2 shows the desired result, but I don't know how to get there in an efficient way without blowing up my memory if this task is done on much larger tables. import pandas as pd import numpy as np df1 = pd.DataFrame(np.array([["A", "X", 3,6,4,0], ["A", "X", 0,2,10,0], ["A", "X", 0,9,3,0], ["A", "Y", 8,3,1,0], ["A", "Y", 0,2,3,0], ["B", "X", 4,4,2,0], ["B", "X", 0,1,0,0]]), columns=['key1', 'key2', 'start', 'plus', 'minus', 'end']) >>> df1 key1 key2 start plus minus end 0 A X 3 6 4 0 1 A X 0 2 10 0 2 A X 0 9 3 0 3 A Y 8 3 1 0 4 A Y 0 2 3 0 5 B X 4 4 2 0 6 B X 0 1 0 0 df2 = pd.DataFrame(np.array([["A", "X", 3,6,4,5], ["A", "X", 5,2,10,-3], ["A", "X", -3,9,3,3], ["A", "Y", 8,3,1,10], ["A", "Y", 10,2,3,9], ["B", "X", 4,4,2,2], ["B", "X", 2,1,0,3]]), columns=['key1', 'key2', 'start', 'plus', 'minus', 'end']) >>> df2 key1 key2 start plus minus end 0 A X 3 6 4 5 1 A X 5 2 10 -3 2 A X -3 9 3 3 3 A Y 8 3 1 10 4 A Y 10 2 3 9 5 B X 4 4 2 2 6 B X 2 1 0 3 

Answer: You can create helper Series for subtract plus and minus columns, create cumulative sums per groups by both columns and add first value of start for final end column, then for start column use DataFrameGroupBy.shift with replace first value by original values in Series.fillna: plusminus = df1['plus'].sub(df1['minus']) df1 = df1.assign(plusminus = plusminus) g = df1.groupby(['key1','key2']) df1['end'] = g['plusminus'].cumsum().add(g['start'].transform('first')) df1['start'] = g['end'].shift().fillna(df1['start']).astype(int) df1 = df1.drop('plusminus', axis=1) print (df1) key1 key2 start plus minus end 0 A X 3 6 4 5 1 A X 5 2 1 6 2 A X 6 5 7 4 3 A Y 8 3 1 10 4 A Y 10 2 3 9 5 B X 4 4 2 6 6 B X 6 1 0 7
Question: I was going through official documentation of Popen.communicate(). p = subprocess.Popen('echo hello',stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True,universal_newlines=True) r,e = p.communicate()  I want to know at which case it will return string output and which case it will return in bytes.(with example would be great) In the above case r type is string. Popen.communicate(input=None, timeout=None) Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate and set the returncode attribute. The optional input argument should be data to be sent to the child process, or None, if no data should be sent to the child. If streams were opened in text mode, input must be a string. Otherwise, it must be bytes. communicate() returns a tuple (stdout_data, stderr_data). The data will be strings if streams were opened in text mode; otherwise, bytes. 

Answer: It depends on the text mode used as per the docs  If encoding or errors are specified, or text (also known as universal_newlines) is true, the file objects stdin, stdout and stderr will be opened in text mode using the encoding and errors specified in the call or the defaults for io.TextIOWrapper... If text mode is not used, stdin, stdout and stderr will be opened as binary streams. No encoding or line ending conversion is performed.  For future use-cases on well typed libraries, you can use typing.reveal_type with static analyzers such as mypy. This makes it quite easy to determine values in your code. Example, test.py from subprocess import Popen from typing import reveal_type p1 = Popen("blah", text=False) reveal_type(p1.communicate()) p2 = Popen("blah", text=True) reveal_type(p2.communicate())  > mypy test.py test.py:5: note: Revealed type is "Tuple[builtins.bytes, builtins.bytes]" test.py:9: note: Revealed type is "Tuple[builtins.str, builtins.str]" Success: no issues found in 1 source file  You can see here, when text=False the values are bytes, when text=True the values are strings.
Question: I have a dataset where I would like to de aggregate the values into their own unique rows as well as perform a pivot, grouping by category. Data updated Period Date Area BB stat AA stat CC stat DD stat BB test AA test CC test DD test BB re AA re CC re BB test2 AA test2 CC test2 DD test2 8/1/2016 9/1/2016 NY 5 5 5 1 1 1 0 0 0 0 0 0 0 9/1/2016 10/1/2016 NY 6 6 6 4 4 4 0 0 0 0 0 0 0 8/1/2016 9/1/2016 CA 2 2 2 4 4 4 0 0 0 0 0 0 0 9/1/2016 10/1/2016 CA 1 1 1 -2 -2 -2 0 0 0 0 0 0 0  Desired Period Date Area stat test type re test2 8/1/2016 9/1/2016 NY 5 1 BB 0 0 9/1/2016 10/1/2016 NY 6 4 BB 0 0 8/1/2016 9/1/2016 NY 5 1 AA 0 0 9/1/2016 10/1/2016 NY 6 4 AA 0 0 8/1/2016 9/1/2016 NY 5 1 CC 0 0 9/1/2016 10/1/2016 NY 6 4 CC 0 0 8/1/2016 9/1/2016 NY 0 0 DD 0 0 9/1/2016 10/1/2016 NY 0 0 DD 0 0 8/1/2016 9/1/2016 CA 2 4 BB 0 0 9/1/2016 10/1/2016 CA 1 -2 BB 0 0 8/1/2016 9/1/2016 CA 2 4 AA 0 0 9/1/2016 10/1/2016 CA 1 -2 AA 0 0 8/1/2016 9/1/2016 CA 2 4 CC 0 0 9/1/2016 10/1/2016 CA 1 -2 CC 0 0 8/1/2016 9/1/2016 CA 0 0 DD 0 0 9/1/2016 10/1/2016 CA 0 0 DD 0 0  Doing value_vars = ["BB stat", "AA stat", "CC stat", "DD stat", "BB test", "AA test", "CC test", "DD test", "BB re", "AA re", "CC re"] df = df.melt(id_vars=["Period", "Date", "Area"], value_vars=value_vars) temp_df = df.variable.str.split("_", 1, expand=True) df["type"] = temp_df[0] df["name"] = temp_df[1] df = df.drop(columns=["variable"]) first_half = df.iloc[:len(df)//2] second_half = df.iloc[len(df)//2:] df = pd.merge(first_half, second_half, on=["Period", "Date", "Area", "type"], suffixes=("_1", "_2")) df.rename(columns = {'value_3':'stat''value_2':'test', 'value_1':'re'}, inplace = True) df.drop(columns=["name_1", "name_2"], inplace=True) df = df[[ "Period", "Date", "Area", "stat", "test", "type", "re" ]] df.sort_values(["Area", "type"], ascending=False, inplace=True) df.to_markdown()  The following code fails to capture all the output columns. Any suggestion is appreciated.

Answer: Try pd.wide_to_long: pd.wide_to_long(df, stubnames=['AA', 'BB','CC','DD'], i=['Period','Date','Area'], j='', sep=' ', suffix='(test|re|stat)' ).unstack(level=-1, fill_value=0).stack(level=0).reset_index()  Output:  Period Date Area type re stat test 0 8/1/2016 9/1/2016 CA AA 0.0 2.0 4.0 1 8/1/2016 9/1/2016 CA BB 0.0 2.0 4.0 2 8/1/2016 9/1/2016 CA CC 0.0 2.0 4.0 3 8/1/2016 9/1/2016 CA DD NaN 0.0 0.0 4 8/1/2016 9/1/2016 NY AA 0.0 5.0 1.0 5 8/1/2016 9/1/2016 NY BB 0.0 5.0 1.0 6 8/1/2016 9/1/2016 NY CC 0.0 5.0 1.0 7 8/1/2016 9/1/2016 NY DD NaN 0.0 0.0 8 9/1/2016 10/1/2016 CA AA 0.0 1.0 -2.0 9 9/1/2016 10/1/2016 CA BB 0.0 1.0 -2.0 10 9/1/2016 10/1/2016 CA CC 0.0 1.0 -2.0 11 9/1/2016 10/1/2016 CA DD NaN 0.0 0.0 12 9/1/2016 10/1/2016 NY AA 0.0 6.0 4.0 13 9/1/2016 10/1/2016 NY BB 0.0 6.0 4.0 14 9/1/2016 10/1/2016 NY CC 0.0 6.0 4.0 15 9/1/2016 10/1/2016 NY DD NaN 0.0 0.0
Question: I have a tricky with date format with time series data. In my dataframe of over one hundred thousand rows I have a column datetime with date value but the format is %M:%S.%f. Example: datetime 0 59:57.7 1 00:09.7 2 00:21.8  What I want in output is to convert this format to %m/%d/%Y %H:%M:%S.%f with 01/01/2023 00:59:57.7 as first date and then increment hours and day. It's a time series data on few days. Result: datetime ProcessTime 59:57.7 01/01/2023 00:59:57.7 00:09.7 01/01/2023 01:00:09.7 00:21.8 01/01/2023 01:00:21.8  I did this code to change the first date to try to have a referential and change the others. import pandas as pd from datetime import datetime # Example dataframe df = pd.DataFrame({'datetime': ['59:57.7', '00:09.7', '00:21.8']}) first_time_str = df['datetime'][0] first_time_obj = datetime.strptime(first_time_str, '%M:%S.%f') formatted_first_time = first_time_obj.replace(year=2023, month=1, day=1).strftime('%m/%d/%Y %H:%M:%S.%f') df['datetime'][0] = formatted_first_time  Thanks for your help. Regards

Answer: The exact logic is unclear assuming a cumulated time You can convert to_timedelta (after adding the missing hours '00:'), then get the cumsum and add the reference date: df['ProcessTime'] = (pd.to_timedelta('00:'+df['datetime']).cumsum() .add(pd.Timestamp('2023-01-01 00:59:57.7')) .dt.strftime('%m/%d/%Y %H:%M:%S.%f') )  Output:  datetime ProcessTime 0 59:57.7 01/01/2023 01:59:55.400000 1 00:09.7 01/01/2023 02:00:05.100000 2 00:21.8 01/01/2023 02:00:26.900000  assuming simple timedelta df['ProcessTime'] = (pd.to_timedelta('00:'+df['datetime']) .add(pd.Timestamp('2023-01-01')) .dt.strftime('%m/%d/%Y %H:%M:%S.%f') )  Output:  datetime ProcessTime 0 59:57.7 01/01/2023 00:59:57.700000 1 00:09.7 01/01/2023 01:00:07.400000 2 00:21.8 01/01/2023 01:00:29.200000  assuming you want to add 1h when the timedelta gets smaller than the previous one t = pd.to_timedelta('00:'+df['datetime']) df['ProcessTime'] = (pd.to_timedelta(t.diff().lt('0').cumsum(), unit='h') .add(t+pd.Timestamp('2023-01-01')) .dt.strftime('%m/%d/%Y %H:%M:%S.%f') )  Output:  datetime ProcessTime 0 59:57.7 01/01/2023 00:59:57.700000 1 00:09.7 01/01/2023 01:00:09.700000 2 00:21.8 01/01/2023 01:00:21.800000
Question: Given the following table: df = pd.DataFrame({'code':['100M','60M10N40M','5S99M','1S25I100M','1D1S1I200M']})  that looks like this:  code 0 100M 1 60M10N40M 2 5S99M 3 1S25I100M 4 1D1S1I200M  I'd like to convert the code column strings to numbers where M, N, D are each equivalent to (times 1), I is equivalent to (times -1) and S is equivalent to (times 0). The result should look like this:  code Val 0 100M 100 This is (100*1) 1 60M10N40M 110 This is (60*1)+(10*1)+(40*1) 2 5S99M 99 This is (5*0)+(99*1) 3 1S25I100M 75 This is (1*0)+(25*-1)+(100*1) 4 1D1S1I200M 200 This is (1*1)+(1*0)+(1*-1)+(200*1)  I wrote the following function to this: def String2Val(String): # Generate substrings sstrings = re.findall('.[^A-Z]*.', String) KeyDict = {'M':'*1','N':'*1','I':'*-1','S':'*0','D':'*1'} newlist = [] for key, value in KeyDict.items(): for i in sstrings: if key in i: p = i.replace(key, value) lp = eval(p) newlist.append(lp) OutputVal = sum(newlist) return OutputVal df['Val'] = df.apply(lambda row: String2Val(row['code']), axis = 1)  After applying this function to the table, I realized it's not efficient and takes forever when applied to large datasets. How can I optimize this process?

Answer: Since pandas string methods are not optimized (although that seems to no longer be true for pandas 2.0), if you're after performance, it's better to use Python string methods in a loop (which are compiled in C). It seems a straightforward loop over each string might give the best performance. def evaluater(s): total, curr = 0, '' for e in s: # if a number concatenate to the previous number if e.isdigit(): curr += e # if a string, look up its value in KeyDict # and multiply the currently collected number by it # and add to the total else: total += int(curr) * KeyDict[e] curr = '' return total KeyDict = {'M': 1, 'N': 1, 'I': -1, 'S': 0, 'D': 1} df['val'] = df['code'].map(evaluater)  Performance: KeyDict1 = {'M':'*1+','N':'*1+','I':'*-1+','S':'*0+','D':'*1+'} df = pd.DataFrame({'code':['100M','60M10N40M','5S99M','1S25I100M','1D1S1I200M']*1000}) %timeit df.assign(val=df['code'].map(evaluater)) # 12.2 ms ± 579 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) %timeit df.assign(val=df['code'].apply(String2Val)) # @Marcelo Paco # 61.8 ms ± 2.47 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) %timeit df.assign(val=df['code'].replace(KeyDict1, regex=True).str.rstrip('+').apply(pd.eval)) # @Ynjxsjmh # 4.86 s ± 155 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)  N.B. You already implement something similar but the outer loop (for key, value in KeyDict.items()) is unnecessary; since KeyDict is a dictionary, use it as a lookup table; don't loop. Also, .apply(axis=1) is a really bad way to loop when only a single column is relevant. Select that column and call apply().
Question: Let's say I have a Polars dataframe like so: df = pl.DataFrame({ 'a': [0.3, 0.7, 0.5, 0.1, 0.9] })  And now I need to add a new column where 1 or 0 is assigned depending on whether a value in column 'a' is greater or less than some threshold. In Pandas I can do this: import numpy as np THRESHOLD = 0.5 df['new'] = np.where(df.a > THRESHOLD, 0, 1)  I can also do something very similar in Polars: df = df.with_columns( pl.lit(np.where(df.select('a').to_numpy() > THRESHOLD, 0, 1).ravel()) .alias('new') )  This works fine but I'm sure that using NumPy here is not the best practice. I've also tried something more like: df = df.with_columns( pl.lit(df.filter(pl.col('a') > THRESHOLD).select([0, 1])) .alias('new') )  But with this syntax I keep running into the following error: DuplicateError Traceback (most recent call last) Cell In[47], line 5 1 THRESHOLD = 0.5 2 DELAY_TOLERANCE = 10 4 df = df.with_columns( ----> 5 pl.lit(df.filter(pl.col('a') > THRESHOLD).select([0, 1])) 6 .alias('new') 7 ) 8 df.head() DuplicateError: column with name 'literal' has more than one occurrences  So my question is two-fold: what am I doing wrong here and what is the best practice in Polars for such conditional assignments? I did looks through docs and previous questions but couldn't find anything resembling my use-case.

Answer: The select([0, 1]) doesn't really make a lot of sense Polars-wise, you're just selecting a literal. Not quite sure why that's throwing a DuplicateError as is. Conditionals in polars are best done with when: df.with_columns(pl.when(pl.col("a") > 0.5).then(0).otherwise(1).alias("b"))
Question: Can someone please assist how to fix this issue, why i am getting this error while running the Ansible playbook  2023-03-31 11:47:39,902 p=57332 u=NI40153964 n=ansible | An exception occurred during task execution. To see the full traceback, use -vvv. The error was: re.error: global flags not at the start of the expression at position 1 2023-03-31 11:47:39,903 p=57332  Python & Ansible versions:  Python 3.11.2 Ansible [core 2.14.3]  The YML file which I am using as  - name: rename log file to user specific delegate_to: localhost command: mv ~/.ansible/wmDeployment.log ~/.ansible/wmDeployment_{{_user}}.log register: logfile_rename_output run_once: true ignore_errors: yes - name: set the fact for email set_fact: package_list: "{{hostvars['localhost']['package_list']}}" log_output: "{{log_data| regex_search('((?s)(?<=This task is to install package in target servers).*?(?=This task is to enable kafka consumers and send mail of playbook log))')}}" emailkey: code cacheable: true 

Answer: The error message is saying you need to put the (?s) at the very beginning of the regex. Alternatively, try something like  log_output: "{{log_data| regex_search('(?s:(?<=This task is to install package in target servers)(.*?)(?=This task is to enable kafka consumers and send mail of playbook log))"  In some more detail, (?s) says "I want the s flag for everything here" or, in other words, a global flag. Python requires this to go at the very beginning of the regex, presumably to avoid weird and hard-to-debug problems which could happen if you had (?s) embedded somewhere in the middle of a long and complex regex. In fact, you could even argue that it's more likely a programming mistake than a considered, conscious decision. By contrast, (?s:...) says "I want to apply the s flag to the following subexpression," up to just before the closing parenthesis; this is obviously local to just the parenthesized subexpression, and could not be expressed by any other means. In this concrete example, ((?s)foo) is invalid, but equivalent to either (?s)(foo) or (?s:(foo)) (or, in practice, ((?s:foo)); or, if you don't actually care about the capturing group, simply (?s:foo)).
Question: I am trying to save a figure using tikzplotlib. However, I am encountering an AttributeError: 'Legend' object has no attribute '_ncol'. I am currently using tikzplotlib version 0.10.1 and matplotlib version 3.7.0. Without using "plt.legend()" everything works. Below is an example that is not working: import numpy as np import matplotlib.pyplot as plt import tikzplotlib # Data x = np.linspace(0, 10, 100) y1 = np.sin(x) y2 = np.cos(x) y3 = np.tan(x) # Plotting plt.figure() plt.plot(x, y1, label='sin(x)') plt.plot(x, y2, label='cos(x)') plt.plot(x, y3, label='tan(x)') plt.legend() # Save as TikZ file tikzplotlib.save("plot.tikz") 

Answer: Hey I have/had the same problem, the problem is that with matplotlib 3.6 the interface changed. There is already a fix (#558) for tikzplotlib on GitHub, but it looks like nothing will happen for now. However, there is a workaround for the issue on GitHub (Issue). It works quite well. I hope that this answer will soon become obsolete. For the sake of completeness, I'll add the code here again. def tikzplotlib_fix_ncols(obj): """ workaround for matplotlib 3.6 renamed legend's _ncol to _ncols, which breaks tikzplotlib """ if hasattr(obj, "_ncols"): obj._ncol = obj._ncols for child in obj.get_children(): tikzplotlib_fix_ncols(child)  Disclaimer: This is not my code. But this problem can be very annoying and that's why I'm sharing the code here. The author is st--